## [Pre-allocating outputs](#Pre-allocating-outputs)
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.
Sometimes you can circumvent the need to allocate memory on each function call by preallocating the output. As a trivial example, compare
```julia-repl
julia> function xinc(x)
           return [x, x+1, x+2]
       end;

julia> function loopinc()
           y = 0
           for i = 1:10^7
               ret = xinc(i)
               y += ret[2]
           end
           return y
       end;
```
with
```julia-repl
julia> function xinc!(ret::AbstractVector{T}, x::T) where T
           ret[1] = x
           ret[2] = x+1
           ret[3] = x+2
           nothing
       end;

julia> function loopinc_prealloc()
           ret = Vector{Int}(undef, 3)
           y = 0
           for i = 1:10^7
               xinc!(ret, i)
               y += ret[2]
           end
           return y
       end;
```
Timing results:
```julia-repl
julia> @time loopinc()
  0.529894 seconds (40.00 M allocations: 1.490 GiB, 12.14% gc time)
50000015000000

julia> @time loopinc_prealloc()
  0.030850 seconds (6 allocations: 288 bytes)
50000015000000
```
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`](../../base/arrays/#Core.Array), had we so desired.


## [Pre-allocating outputs](#Pre-allocating-outputs)
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](../functions/#man-vectorized)).


## [Use MutableArithmetics for more control over allocation for mutable arithmetic types](#man-perftips-mutablearithmetics)
Some [`Number`](../../base/numbers/#Core.Number) subtypes, such as [`BigInt`](../../base/numbers/#Base.GMP.BigInt) or [`BigFloat`](../../base/numbers/#Base.MPFR.BigFloat), may be implemented as [`mutable struct`](../../base/base/#mutable%20struct) 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`](https://juliahub.com/ui/Packages/General/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.


## [More dots: Fuse vectorized operations](#More-dots:-Fuse-vectorized-operations)
Julia has a special [dot syntax](../functions/#man-vectorized) 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).
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:
```julia-repl
julia> f(x) = 3x.^2 + 4x + 7x.^3;

julia> fdot(x) = @. 3x^2 + 4x + 7x^3; # equivalent to 3 .* x.^2 .+ 4 .* x .+ 7 .* x.^3
```
Both `f` and `fdot` compute the same thing. However, `fdot` (defined with the help of the [`@.`](../../base/arrays/#Base.Broadcast.@__dot__) macro) is significantly faster when applied to an array:
```julia-repl
julia> x = rand(10^6);

julia> @time f(x);
  0.019049 seconds (16 allocations: 45.777 MiB, 18.59% gc time)

julia> @time fdot(x);
  0.002790 seconds (6 allocations: 7.630 MiB)

julia> @time f.(x);
  0.002626 seconds (8 allocations: 7.630 MiB)
```


## [More dots: Fuse vectorized operations](#More-dots:-Fuse-vectorized-operations)
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.


## [Fewer dots: Unfuse certain intermediate broadcasts](#man-performance-unfuse)
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:
```julia
julia> x = rand(1000, 1000);

julia> d = sum(abs2, x; dims=2);

julia> @time x ./= sqrt.(d);
  0.002049 seconds (4 allocations: 96 bytes)
```
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.


## [Fewer dots: Unfuse certain intermediate broadcasts](#man-performance-unfuse)
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.
```julia
julia> @time let s = sqrt.(d); x ./= s end;
  0.000809 seconds (5 allocations: 8.031 KiB)

julia> @time x ./= identity(sqrt.(d));
  0.000608 seconds (5 allocations: 8.031 KiB)

julia> @time x ./= map(sqrt, d);
  0.000611 seconds (4 allocations: 8.016 KiB)
```
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.


## [Consider using views for slices](#man-performance-views)
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.
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`](../../base/arrays/#Base.view), or more simply for a whole expression or block of code by putting [`@views`](../../base/arrays/#Base.@views) in front of that expression. For example:
```julia-repl
julia> fcopy(x) = sum(x[2:end-1]);

julia> @views fview(x) = sum(x[2:end-1]);

julia> x = rand(10^6);

julia> @time fcopy(x);
  0.003051 seconds (3 allocations: 7.629 MB)

julia> @time fview(x);
  0.001020 seconds (1 allocation: 16 bytes)
```
Notice both the 3× speedup and the decreased memory allocation of the `fview` version of the function.


## [Copying data is not always bad](#Copying-data-is-not-always-bad)
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.
Copying irregularly-accessed data into a contiguous array before repeated access 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.
```julia-repl
julia> using Random

julia> A = randn(3000, 3000);

julia> x = randn(2000);

julia> inds = shuffle(1:3000)[1:2000];

julia> function iterated_neural_network(A, x, depth)
           for _ in 1:depth
               x .= max.(0, A * x)
           end
           argmax(x)
       end

julia> @time iterated_neural_network(view(A, inds, inds), x, 10)
  0.324903 seconds (12 allocations: 157.562 KiB)
1569

julia> @time iterated_neural_network(A[inds, inds], x, 10)
  0.054576 seconds (13 allocations: 30.671 MiB, 13.33% gc time)
1569
```
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.


## [Consider StaticArrays.jl for small fixed-size vector/matrix operations](#Consider-StaticArrays.jl-for-small-fixed-size-vector/matrix-operations)
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](https://github.com/JuliaArrays/StaticArrays.jl). 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.
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])`.


## [Avoid string interpolation for I/O](#Avoid-string-interpolation-for-I/O)
When writing data to a file (or other I/O device), forming extra intermediate strings is a source of overhead. Instead of:
```julia
println(file, "$a $b")
```
use:
```julia
println(file, a, " ", b)
```
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:
```julia
println(file, "$(f(a))$(f(b))")
```
versus:
```julia
println(file, f(a), f(b))
```


## [Optimize network I/O during parallel execution](#Optimize-network-I/O-during-parallel-execution)
When executing a remote function in parallel:
```julia
using Distributed

responses = Vector{Any}(undef, nworkers())
@sync begin
    for (idx, pid) in enumerate(workers())
        @async responses[idx] = remotecall_fetch(foo, pid, args...)
    end
end
```
is faster than:
```julia
using Distributed

refs = Vector{Any}(undef, nworkers())
for (idx, pid) in enumerate(workers())
    refs[idx] = @spawnat pid foo(args...)
end
responses = [fetch(r) for r in refs]
```
The former results in a single network round-trip to every worker, while the latter results in two network calls - first by the [`@spawnat`](../../stdlib/Distributed/#Distributed.@spawnat) and the second due to the [`fetch`](../../base/parallel/#Base.fetch-Tuple%7BTask%7D) (or even a [`wait`](../../base/parallel/#Base.wait)). The [`fetch`](../../base/parallel/#Base.fetch-Tuple%7BTask%7D)/[`wait`](../../base/parallel/#Base.wait) is also being executed serially resulting in an overall poorer performance.


## [Fix deprecation warnings](#Fix-deprecation-warnings)
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.


## [Tweaks](#Tweaks)
These are some minor points that might help in tight inner loops.
-   Avoid unnecessary arrays. For example, instead of [`sum([x,y,z])`](../../base/collections/#Base.sum) use `x+y+z`.
-   Use [`abs2(z)`](../../base/math/#Base.abs2) instead of [`abs(z)^2`](../../base/math/#Base.:%5E-Tuple%7BNumber,%20Number%7D) for complex `z`. In general, try to rewrite code to use [`abs2`](../../base/math/#Base.abs2) instead of [`abs`](../../base/math/#Base.abs) for complex arguments.
-   Use [`div(x,y)`](../../base/math/#Base.div) for truncating division of integers instead of [`trunc(x/y)`](../../base/math/#Base.trunc), [`fld(x,y)`](../../base/math/#Base.fld) instead of [`floor(x/y)`](../../base/math/#Base.floor), and [`cld(x,y)`](../../base/math/#Base.cld) instead of [`ceil(x/y)`](../../base/math/#Base.ceil).


## [Performance Annotations](#man-performance-annotations)
Sometimes you can enable better optimization by promising certain program properties.
-   Use [`@inbounds`](../../base/base/#Base.@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.
-   Use [`@fastmath`](../../base/math/#Base.FastMath.@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.
-   Write [`@simd`](../../base/base/#Base.SimdLoop.@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.


## [Performance Annotations](#man-performance-annotations)
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](../../devdocs/offset-arrays/#man-custom-indices)).
While `@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 ...`.
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):
```julia
@noinline function inner(x, y)
    s = zero(eltype(x))
    for i=eachindex(x)
        @inbounds s += x[i]*y[i]
    end
    return s
end

@noinline function innersimd(x, y)
    s = zero(eltype(x))
    @simd for i = eachindex(x)
        @inbounds s += x[i] * y[i]
    end
    return s
end

function timeit(n, reps)
    x = rand(Float32, n)
    y = rand(Float32, n)
    s = zero(Float64)
    time = @elapsed for j in 1:reps
        s += inner(x, y)
    end
    println("GFlop/sec        = ", 2n*reps / time*1E-9)
    time = @elapsed for j in 1:reps
        s += innersimd(x, y)
    end
    println("GFlop/sec (SIMD) = ", 2n*reps / time*1E-9)
end

timeit(1000, 1000)
```
On a computer with a 2.4GHz Intel Core i5 processor, this produces:


## [Performance Annotations](#man-performance-annotations)
```julia
GFlop/sec        = 1.9467069505224963
GFlop/sec (SIMD) = 17.578554163920018
```
(`GFlop/sec` measures the performance, and larger numbers are better.)
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:
```julia
function init!(u::Vector)
    n = length(u)
    dx = 1.0 / (n-1)
    @fastmath @inbounds @simd for i in 1:n #by asserting that `u` is a `Vector` we can assume it has 1-based indexing
        u[i] = sin(2pi*dx*i)
    end
end

function deriv!(u::Vector, du)
    n = length(u)
    dx = 1.0 / (n-1)
    @fastmath @inbounds du[1] = (u[2] - u[1]) / dx
    @fastmath @inbounds @simd for i in 2:n-1
        du[i] = (u[i+1] - u[i-1]) / (2*dx)
    end
    @fastmath @inbounds du[n] = (u[n] - u[n-1]) / dx
end

function mynorm(u::Vector)
    n = length(u)
    T = eltype(u)
    s = zero(T)
    @fastmath @inbounds @simd for i in 1:n
        s += u[i]^2
    end
    @fastmath @inbounds return sqrt(s)
end

function main()
    n = 2000
    u = Vector{Float64}(undef, n)
    init!(u)
    du = similar(u)

    deriv!(u, du)
    nu = mynorm(du)

    @time for i in 1:10^6
        deriv!(u, du)
        nu = mynorm(du)
    end

    println(nu)
end

main()
```
On a computer with a 2.7 GHz Intel Core i7 processor, this produces:
```julia
$ julia wave.jl;
  1.207814709 seconds
4.443986180758249

$ julia --math-mode=ieee wave.jl;
  4.487083643 seconds
4.443986180758249
```


## [Performance Annotations](#man-performance-annotations)
Here, the option `--math-mode=ieee` disables the `@fastmath` macro, so that we can compare results.
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.
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`](../../stdlib/InteractiveUtils/#InteractiveUtils.code_native) function.


## [Performance Annotations](#man-performance-annotations)
Note that `@fastmath` also assumes that `NaN`s will not occur during the computation, which can lead to surprising behavior:
```julia-repl
julia> f(x) = isnan(x);

julia> f(NaN)
true

julia> f_fast(x) = @fastmath isnan(x);

julia> f_fast(NaN)
false
```


## [Treat Subnormal Numbers as Zeros](#Treat-Subnormal-Numbers-as-Zeros)
Subnormal numbers, formerly called [denormal numbers](https://en.wikipedia.org/wiki/Denormal_number), are useful in many contexts, but incur a performance penalty on some hardware. A call [`set_zero_subnormals(true)`](../../base/numbers/#Base.Rounding.set_zero_subnormals) 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)`](../../base/numbers/#Base.Rounding.set_zero_subnormals) enforces strict IEEE behavior for subnormal numbers.
Below is an example where subnormals noticeably impact performance on some hardware:
```julia
function timestep(b::Vector{T}, a::Vector{T}, Δt::T) where T
    @assert length(a)==length(b)
    n = length(b)
    b[1] = 1                            # Boundary condition
    for i=2:n-1
        b[i] = a[i] + (a[i-1] - T(2)*a[i] + a[i+1]) * Δt
    end
    b[n] = 0                            # Boundary condition
end

function heatflow(a::Vector{T}, nstep::Integer) where T
    b = similar(a)
    for t=1:div(nstep,2)                # Assume nstep is even
        timestep(b,a,T(0.1))
        timestep(a,b,T(0.1))
    end
end

heatflow(zeros(Float32,10),2)           # Force compilation
for trial=1:6
    a = zeros(Float32,1000)
    set_zero_subnormals(iseven(trial))  # Odd trials use strict IEEE arithmetic
    @time heatflow(a,1000)
end
```
This gives an output similar to


## [Treat Subnormal Numbers as Zeros](#Treat-Subnormal-Numbers-as-Zeros)
```julia
  0.002202 seconds (1 allocation: 4.063 KiB)
  0.001502 seconds (1 allocation: 4.063 KiB)
  0.002139 seconds (1 allocation: 4.063 KiB)
  0.001454 seconds (1 allocation: 4.063 KiB)
  0.002115 seconds (1 allocation: 4.063 KiB)
  0.001455 seconds (1 allocation: 4.063 KiB)
```
Note how each even iteration is significantly faster.
This example generates many subnormal numbers because the values in `a` become an exponentially decreasing curve, which slowly flattens out over time.
Treating subnormals as zeros should be used with caution, because doing so breaks some identities, such as `x-y == 0` implies `x == y`:
```julia-repl
julia> x = 3f-38; y = 2f-38;

julia> set_zero_subnormals(true); (x - y, x == y)
(0.0f0, false)

julia> set_zero_subnormals(false); (x - y, x == y)
(1.0000001f-38, false)
```
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:
```julia
a = rand(Float32,1000) * 1.f-9
```


## [`@code_warntype`](../../stdlib/InteractiveUtils/#InteractiveUtils.@code_warntype)
The macro [`@code_warntype`](../../stdlib/InteractiveUtils/#InteractiveUtils.@code_warntype) (or its function variant [`code_warntype`](../../stdlib/InteractiveUtils/#InteractiveUtils.code_warntype)) can sometimes be helpful in diagnosing type-related problems. Here's an example:
```julia-repl
julia> @noinline pos(x) = x < 0 ? 0 : x;

julia> function f(x)
           y = pos(x)
           return sin(y*x + 1)
       end;

julia> @code_warntype f(3.2)
MethodInstance for f(::Float64)
  from f(x) @ Main REPL[9]:1
Arguments
  #self#::Core.Const(f)
  x::Float64
Locals
  y::Union{Float64, Int64}
Body::Float64
1 ─      (y = Main.pos(x))
│   %2 = (y * x)::Float64
│   %3 = (%2 + 1)::Float64
│   %4 = Main.sin(%3)::Float64
└──      return %4
```


## [`@code_warntype`](../../stdlib/InteractiveUtils/#InteractiveUtils.@code_warntype)
Interpreting the output of [`@code_warntype`](../../stdlib/InteractiveUtils/#InteractiveUtils.@code_warntype), like that of its cousins [`@code_lowered`](../../stdlib/InteractiveUtils/#InteractiveUtils.@code_lowered), [`@code_typed`](../../stdlib/InteractiveUtils/#InteractiveUtils.@code_typed), [`@code_llvm`](../../stdlib/InteractiveUtils/#InteractiveUtils.@code_llvm), and [`@code_native`](../../stdlib/InteractiveUtils/#InteractiveUtils.@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`](../../base/numbers/#Core.Float64), for example). The most important characteristic of [`@code_warntype`](../../stdlib/InteractiveUtils/#InteractiveUtils.@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.


## [`@code_warntype`](../../stdlib/InteractiveUtils/#InteractiveUtils.@code_warntype)
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*x`is 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.


## [`@code_warntype`](../../stdlib/InteractiveUtils/#InteractiveUtils.@code_warntype)
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`](../../base/numbers/#Core.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`](../../base/arrays/#Base.findfirst-Tuple%7BAny%7D) 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, `Union`s containing either `missing` or `nothing` are color highlighted in yellow, instead of red.
The following examples may help you interpret expressions marked as containing non-leaf types:
-   Function body starting with `Body::Union{T1,T2})`
    -   Interpretation: function with unstable return type


## [`@code_warntype`](../../stdlib/InteractiveUtils/#InteractiveUtils.@code_warntype)
    -   Suggestion: make the return value type-stable, even if you have to annotate it
-   `invoke Main.g(%%x::Int64)::Union{Float64, Int64}`
    -   Interpretation: call to a type-unstable function `g`.
    -   Suggestion: fix the function, or if necessary annotate the return value
-   `invoke Base.getindex(%%x::Array{Any,1}, 1::Int64)::Any`
    -   Interpretation: accessing elements of poorly-typed arrays
    -   Suggestion: use arrays with better-defined types, or if necessary annotate the type of individual element accesses
-   `Base.getfield(%%x, :(:data))::Array{Float64,N} where N`
    -   Interpretation: 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.
    -   Suggestion: use concrete types like `Array{T,3}` or `Array{T,N}`, where `N` is now a parameter of `ArrayContainer`


## [Performance of captured variable](#man-performance-captured)
Consider the following example that defines an inner function:
```julia
function abmult(r::Int)
    if r < 0
        r = -r
    end
    f = x -> x * r
    return f
end
```
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.
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`.
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.


## [Performance of captured variable](#man-performance-captured)
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.
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):
```julia
function abmult2(r0::Int)
    r::Int = r0
    if r < 0
        r = -r
    end
    f = x -> x * r
    return f
end
```
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.
```julia
function abmult3(r::Int)
    if r < 0
        r = -r
    end
    f = let r = r
            x -> x * r
    end
    return f
end
```


## [Performance of captured variable](#man-performance-captured)
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](https://github.com/c42f/FastClosures.jl) automate the insertion of `let` statements as in `abmult3`.


## [Multithreading and linear algebra](#man-multithreading-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:
-   If `OPENBLAS_NUM_THREADS=1`, OpenBLAS uses the calling Julia thread(s), i.e. it "lives in" the Julia thread that runs the computation.
-   If `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.


## [Multithreading and linear algebra](#man-multithreading-linear-algebra)
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](#man-backends-linear-algebra)
As an alternative to OpenBLAS, there exist several other backends that can help with linear algebra performance. Prominent examples include [MKL.jl](https://github.com/JuliaLinearAlgebra/MKL.jl) and [AppleAccelerate.jl](https://github.com/JuliaMath/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).


## [Execution latency, package loading and package precompiling time](#Execution-latency,-package-loading-and-package-precompiling-time)


### [Reducing time to first plot etc.](#Reducing-time-to-first-plot-etc.)
The first time a julia method is called it (and any methods it calls, or ones that can be statically determined) will be compiled. The [`@time`](../profile/#@time) macro family illustrates this.
```julia
julia> foo() = rand(2,2) * rand(2,2)
foo (generic function with 1 method)

julia> @time @eval foo();
  0.252395 seconds (1.12 M allocations: 56.178 MiB, 2.93% gc time, 98.12% compilation time)

julia> @time @eval foo();
  0.000156 seconds (63 allocations: 2.453 KiB)
```
Note that `@time @eval` is better for measuring compilation time because without [`@eval`](../../base/base/#Base.@eval), some compilation may already be done before timing starts.
When developing a package, you may be able to improve the experience of your users with *precompilation* so that when they use the package, the code they use is already compiled. To precompile package code effectively, it's recommended to use [`PrecompileTools.jl`](https://julialang.github.io/PrecompileTools.jl/stable/) to run a "precompile workload" during precompilation time that is representative of typical package usage, which will cache the native compiled code into the package `pkgimage` cache, greatly reducing "time to first execution" (often referred to as TTFX) for such usage.
Note that [`PrecompileTools.jl`](https://julialang.github.io/PrecompileTools.jl/stable/) workloads can be disabled and sometimes configured via Preferences if you do not want to spend the extra time precompiling, which may be the case during development of a package.


### [Reducing package loading time](#Reducing-package-loading-time)
Keeping the time taken to load the package down is usually helpful. General good practice for package developers includes:
1.  Reduce your dependencies to those you really need. Consider using [package extensions](../../base/math/#Base.:--Tuple%7BAny,%20Any%7D) to support interoperability with other packages without bloating your essential dependencies.
2.  Avoid use of [`__init__()`](../../base/base/#__init__) functions unless there is no alternative, especially those which might trigger a lot of compilation, or just take a long time to execute.
3.  Where possible, fix [invalidations](https://julialang.org/blog/2020/08/invalidations/) among your dependencies and from your package code.
The tool [`@time_imports`](../../stdlib/InteractiveUtils/#Base.@time_imports) can be useful in the REPL to review the above factors.


### [Reducing package loading time](#Reducing-package-loading-time)
```julia-repl
julia> @time @time_imports using Plots
      0.5 ms  Printf
     16.4 ms  Dates
      0.7 ms  Statistics
               ┌ 23.8 ms SuiteSparse_jll.__init__() 86.11% compilation time (100% recompilation)
     90.1 ms  SuiteSparse_jll 91.57% compilation time (82% recompilation)
      0.9 ms  Serialization
               ┌ 39.8 ms SparseArrays.CHOLMOD.__init__() 99.47% compilation time (100% recompilation)
    166.9 ms  SparseArrays 23.74% compilation time (100% recompilation)
      0.4 ms  Statistics → SparseArraysExt
      0.5 ms  TOML
      8.0 ms  Preferences
      0.3 ms  PrecompileTools
      0.2 ms  Reexport
... many deps omitted for example ...
      1.4 ms  Tar
               ┌ 73.8 ms p7zip_jll.__init__() 99.93% compilation time (100% recompilation)
     79.4 ms  p7zip_jll 92.91% compilation time (100% recompilation)
               ┌ 27.7 ms GR.GRPreferences.__init__() 99.77% compilation time (100% recompilation)
     43.0 ms  GR 64.26% compilation time (100% recompilation)
               ┌ 2.1 ms Plots.__init__() 91.80% compilation time (100% recompilation)
    300.9 ms  Plots 0.65% compilation time (100% recompilation)
  1.795602 seconds (3.33 M allocations: 190.153 MiB, 7.91% gc time, 39.45% compilation time: 97% of which was recompilation)
```


### [Reducing package loading time](#Reducing-package-loading-time)
Notice that in this example there are multiple packages loaded, some with `__init__()` functions, some of which cause compilation of which some is recompilation. Recompilation is caused by earlier packages invalidating methods, then in these cases when the following packages run their `__init__()` function some hit recompilation before the code can be run.
Further, note the `Statistics` extension `SparseArraysExt` has been activated because `SparseArrays` is in the dependency tree. i.e. see `0.4 ms  Statistics → SparseArraysExt`.
This report gives a good opportunity to review whether the cost of dependency load time is worth the functionality it brings. Also the `Pkg` utility `why` can be used to report why a an indirect dependency exists.
```julia
(CustomPackage) pkg> why FFMPEG_jll
  Plots → FFMPEG → FFMPEG_jll
  Plots → GR → GR_jll → FFMPEG_jll
```
or to see the indirect dependencies that a package brings in, you can `pkg> rm` the package, see the deps that are removed from the manifest, then revert the change with `pkg> undo`.
If loading time is dominated by slow `__init__()` methods having compilation, one verbose way to identify what is being compiled is to use the julia args `--trace-compile=stderr` which will report a [`precompile`](../../base/base/#Base.precompile) statement each time a method is compiled. For instance, the full setup would be:
```julia
$ julia --startup-file=no --trace-compile=stderr
julia> @time @time_imports using CustomPackage
...
```


### [Reducing package loading time](#Reducing-package-loading-time)
Note the `--startup-file=no` which helps isolate the test from packages you may have in your `startup.jl`.
More analysis of the reasons for recompilation can be achieved with the [`SnoopCompile`](https://github.com/timholy/SnoopCompile.jl) package.
------------------------------------------------------------------------


# Workflow Tips · The Julia Language
Source: https://docs.julialang.org/en/v1/manual/workflow-tips/


# [Workflow Tips](#man-workflow-tips)
Here are some tips for working with Julia efficiently.


## [REPL-based workflow](#REPL-based-workflow)
As already elaborated in [The Julia REPL](../../stdlib/REPL/#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.


### [A basic editor/REPL workflow](#A-basic-editor/REPL-workflow)
The most basic Julia workflows involve using a text editor in conjunction with the `julia` command line.
Create a file, say `Tmp.jl`, and include within it
```julia
module Tmp

say_hello() = println("Hello!")

# Your other definitions here

end # module

using .Tmp
```
Then, in the same directory, start the Julia REPL (using the `julia` command). Run the new file as follows:
```julia
julia> include("Tmp.jl")

julia> Tmp.say_hello()
Hello!
```julia
Explore ideas in the REPL. Save good ideas in `Tmp.jl`. To reload the file after it has been changed, just `include` it again.
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.
(Explanation: `struct`s 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")`).
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.


## [Browser-based workflow](#Browser-based-workflow)
There are a few ways to interact with Julia in a browser:
-   Using Pluto notebooks through [Pluto.jl](https://github.com/fonsp/Pluto.jl)
-   Using Jupyter notebooks through [IJulia.jl](https://github.com/JuliaLang/IJulia.jl)


## [Revise-based workflows](#Revise-based-workflows)
Whether you're at the REPL or in IJulia, you can typically improve your development experience with [Revise](https://github.com/timholy/Revise.jl). It is common to configure Revise to start whenever julia is started, as per the instructions in the [Revise documentation](https://timholy.github.io/Revise.jl/stable/). 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:
1.  Put your code in a module somewhere on your load path. There are several options for achieving this, of which two recommended choices are:
    -   For long-term projects, use [PkgTemplates](https://github.com/invenia/PkgTemplates.jl):
        ```julia
        using PkgTemplates
        t = Template()
        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:


## [Revise-based workflows](#Revise-based-workflows)
        ```julia-repl
        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.
2.  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-repl
    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](https://timholy.github.io/Revise.jl/stable/limitations/)).
------------------------------------------------------------------------


# Style Guide · The Julia Language
Source: https://docs.julialang.org/en/v1/manual/style-guide/


# [Style Guide](#Style-Guide)
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.


## [Indentation](#Indentation)
Use 4 spaces per indentation level.


## [Write functions, not just scripts](#Write-functions,-not-just-scripts)
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.
It is also worth emphasizing that functions should take arguments, instead of operating directly on global variables (aside from constants like [`pi`](../../base/numbers/#Base.MathConstants.pi)).


## [Avoid writing overly-specific types](#Avoid-writing-overly-specific-types)
Code should be as generic as possible. Instead of writing:
```julia
Complex{Float64}(x)
```
it's better to use available generic functions:
```julia
complex(float(x))
```
The second version will convert `x` to an appropriate type, instead of always the same type.
This style point is especially relevant to function arguments. For example, don't declare an argument to be of type `Int` or [`Int32`](../../base/numbers/#Core.Int32) if it really could be any integer, expressed with the abstract type [`Integer`](../../base/numbers/#Core.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`](../../base/base/#Core.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](https://en.wikipedia.org/wiki/Duck_typing).)
For example, consider the following definitions of a function `addone` that returns one plus its argument:
```julia
addone(x::Int) = x + 1                 # works only for Int
addone(x::Integer) = x + oneunit(x)    # any integer type
addone(x::Number) = x + oneunit(x)     # any numeric type
addone(x) = x + oneunit(x)             # any type supporting + and oneunit
```


## [Avoid writing overly-specific types](#Avoid-writing-overly-specific-types)
The last definition of `addone` handles any type supporting [`oneunit`](../../base/numbers/#Base.oneunit) (which returns 1 in the same type as `x`, which avoids unwanted type promotion) and the [`+`](../../base/math/#Base.:+) 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.


## [Handle excess argument diversity in the caller](#Handle-excess-argument-diversity-in-the-caller)
Instead of:
```julia
function foo(x, y)
    x = Int(x); y = Int(y)
    ...
end
foo(x, y)
```
use:
```julia
function foo(x::Int, y::Int)
    ...
end
foo(Int(x), Int(y))
```
This is better style because `foo` does not really accept numbers of all types; it really needs `Int` s.
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.


## [Append ! to names of functions that modify their arguments](#bang-convention)
Instead of:
```julia
function double(a::AbstractArray{<:Number})
    for i in eachindex(a)
        a[i] *= 2
    end
    return a
end
```
use:
```julia
function double!(a::AbstractArray{<:Number})
    for i in eachindex(a)
        a[i] *= 2
    end
    return a
end
```
Julia Base uses this convention throughout and contains examples of functions with both copying and modifying forms (e.g., [`sort`](../../base/sort/#Base.sort) and [`sort!`](../../base/sort/#Base.sort!)), and others which are just modifying (e.g., [`push!`](../../base/collections/#Base.push!), [`pop!`](../../base/collections/#Base.pop!), [`splice!`](../../base/collections/#Base.splice!)). It is typical for such functions to also return the modified array for convenience.
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.


## [Avoid strange type Unions](#Avoid-strange-type-Unions)
Types such as `Union{Function,AbstractString}` are often a sign that some design could be cleaner.


## [Avoid elaborate container types](#Avoid-elaborate-container-types)
It is usually not much help to construct arrays like the following:
```julia
a = Vector{Union{Int,AbstractString,Tuple,Array}}(undef, n)
```
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.


## [Prefer exported methods over direct field access](#Prefer-exported-methods-over-direct-field-access)
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:
-   Package developers are freer to change the implementation without breaking user code.
-   Methods can be passed to higher-order constructs like [`map`](../../base/collections/#Base.map) (e.g. `map(imag, zs)`) rather than `[z.im for z in zs]`).
-   Methods can be defined on abstract types.
-   Methods can describe a conceptual operation that can be shared across disparate types (e.g. `real(z)` works on Complex numbers or Quaternions).
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.
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.
Counter-examples to this rule include [`NamedTuple`](../../base/base/#Core.NamedTuple), [`RegexMatch`](../../base/strings/#Base.match), [`StatStruct`](../../base/file/#Base.stat).


## [Use naming conventions consistent with Julia base/](#Use-naming-conventions-consistent-with-Julia-base/)
-   modules and type names use capitalization and camel case: `module SparseArrays`, `struct UnitRange`.
-   functions are lowercase ([`maximum`](../../base/collections/#Base.maximum), [`convert`](../../base/base/#Base.convert)) and, when readable, with multiple words squashed together ([`isequal`](../../base/base/#Base.isequal), [`haskey`](../../base/collections/#Base.haskey)). When necessary, use underscores as word separators. Underscores are also used to indicate a combination of concepts ([`remotecall_fetch`](../../stdlib/Distributed/#Distributed.remotecall_fetch-Tuple%7BAny,%20Integer,%20Vararg%7BAny%7D%7D) as a more efficient implementation of `fetch(remotecall(...))`) or as modifiers.
-   functions mutating at least one of their arguments end in `!`.
-   conciseness is valued, but avoid abbreviation ([`indexin`](../../base/collections/#Base.indexin) rather than `indxin`) as it becomes difficult to remember whether and how particular words are abbreviated.
If a function name requires multiple words, consider whether it might represent more than one concept and might be better split into pieces.


## [Write functions with argument ordering similar to Julia Base](#Write-functions-with-argument-ordering-similar-to-Julia-Base)
As a general rule, the Base library uses the following order of arguments to functions, as applicable:
1.  **Function argument**. Putting a function argument first permits the use of [`do`](../../base/base/#do) blocks for passing multiline anonymous functions.
2.  **I/O stream**. Specifying the `IO` object first permits passing the function to functions such as [`sprint`](../../base/io-network/#Base.sprint), e.g. `sprint(show, x)`.
3.  **Input being mutated**. For example, in [`fill!(x, v)`](../../base/arrays/#Base.fill!), `x` is the object being mutated and it appears before the value to be inserted into `x`.
4.  **Type**. Passing a type typically means that the output will have the given type. In [`parse(Int, "1")`](../../base/numbers/#Base.parse), 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)`](../../base/io-network/#Base.read), the `IO` argument appears before the type, which is in keeping with the order outlined here.
5.  **Input not being mutated**. In `fill!(x, v)`, `v` is *not* being mutated and it comes after `x`.
6.  **Key**. For associative collections, this is the key of the key-value pair(s). For other indexed collections, this is the index.
7.  **Value**. For associative collections, this is the value of the key-value pair(s). In cases like [`fill!(x, v)`](../../base/arrays/#Base.fill!), this is `v`.


## [Write functions with argument ordering similar to Julia Base](#Write-functions-with-argument-ordering-similar-to-Julia-Base)
8.  **Everything else**. Any other arguments.
9.  **Varargs**. 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`](../../base/base/#Core.Tuple), e.g. `Matrix{T}(undef, (1,2))`, or as [`Vararg`](../../base/base/#Core.Vararg)s, e.g. `Matrix{T}(undef, 1, 2)`.
10. **Keyword arguments**. In Julia keyword arguments have to come last anyway in function definitions; they're listed here for the sake of completeness.
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.
There are of course a few exceptions. For example, in [`convert`](../../base/base/#Base.convert), the type should always come first. In [`setindex!`](../../base/collections/#Base.setindex!), the value comes before the indices so that the indices can be provided as varargs.
When designing APIs, adhering to this general order as much as possible is likely to give users of your functions a more consistent experience.


## [Don't overuse try-catch](#Don't-overuse-try-catch)
It is better to avoid errors than to rely on catching them.


## [Don't parenthesize conditions](#Don't-parenthesize-conditions)
Julia doesn't require parens around conditions in `if` and `while`. Write:
```julia
if a == b
```
instead of:
```julia
if (a == b)
```


## [Don't overuse ...](#Don't-overuse-...)
Splicing function arguments can be addictive. Instead of `[a..., b...]`, use simply `[a; b]`, which already concatenates arrays. [`collect(a)`](../../base/collections/#Base.collect-Tuple%7BAny%7D) 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.


## [Ensure constructors return an instance of their own type](#Ensure-constructors-return-an-instance-of-their-own-type)
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](../constructors/#man-constructors) that returns an unexpected type can lead to confusing and unpredictable behavior:
```julia-repl
julia> struct Foo{T}
           x::T
       end

julia> Base.Float64(foo::Foo) = Foo(Float64(foo.x))  # Do not define methods like this

julia> Float64(Foo(3))  # Should return `Float64`
Foo{Float64}(3.0)

julia> Foo{Int}(x) = Foo{Float64}(x)  # Do not define methods like this

julia> Foo{Int}(3)  # Should return `Foo{Int}`
Foo{Float64}(3.0)
```
To maintain code clarity and ensure type consistency, always design constructors to return an instance of the type they are supposed to construct.


## [Don't use unnecessary static parameters](#Don't-use-unnecessary-static-parameters)
A function signature:
```julia
foo(x::T) where {T<:Real} = ...
```
should be written as:
```julia
foo(x::Real) = ...
```
instead, especially if `T` is not used in the function body. Even if `T` is used, it can be replaced with [`typeof(x)`](../../base/base/#Core.typeof) 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.
Note also that container types, specifically may need type parameters in function calls. See the FAQ [Avoid fields with abstract containers](../performance-tips/#Avoid-fields-with-abstract-containers) for more information.


## [Avoid confusion about whether something is an instance or a type](#Avoid-confusion-about-whether-something-is-an-instance-or-a-type)
Sets of definitions like the following are confusing:
```julia
foo(::Type{MyType}) = ...
foo(::MyType) = foo(MyType)
```
Decide whether the concept in question will be written as `MyType` or `MyType()`, and stick to it.
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.
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.


## [Don't overuse macros](#Don't-overuse-macros)
Be aware of when a macro could really be a function instead.
Calling [`eval`](../../base/base/#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.


## [Don't expose unsafe operations at the interface level](#Don't-expose-unsafe-operations-at-the-interface-level)
If you have a type that uses a native pointer:
```julia
mutable struct NativeType
    p::Ptr{UInt8}
    ...
end
```
don't write definitions like the following:
```julia
getindex(x::NativeType, i) = unsafe_load(x.p, i)
```
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.
Such a function should either check the operation to ensure it is safe, or have `unsafe` somewhere in its name to alert callers.


## [Don't overload methods of base container types](#Don't-overload-methods-of-base-container-types)
It is possible to write definitions like the following:
```julia
show(io::IO, v::Vector{MyType}) = ...
```
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.


## [Avoid type piracy](#avoid-type-piracy)
"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.
As an example, suppose you wanted to define multiplication on symbols in a module:
```julia
module A
import Base.*
*(x::Symbol, y::Symbol) = Symbol(x,y)
end
```
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 `Symbol`s in another type that you define.
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.


## [Be careful with type equality](#Be-careful-with-type-equality)
You generally want to use [`isa`](../../base/base/#Core.isa) and [`<:`](../../base/base/#Core.:%3C:) 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.


## [Don't write a trivial anonymous function x->f(x) for a named function f](#Don't-write-a-trivial-anonymous-function-x-f(x)-for-a-named-function-f)
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)`](../../base/collections/#Base.map).


## [Avoid using floats for numeric literals in generic code when possible](#Avoid-using-floats-for-numeric-literals-in-generic-code-when-possible)
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.
For example,
```julia-repl
julia> f(x) = 2.0 * x
f (generic function with 1 method)

julia> f(1//2)
1.0

julia> f(1/2)
1.0

julia> f(1)
2.0
```
while
```julia-repl
julia> g(x) = 2 * x
g (generic function with 1 method)

julia> g(1//2)
1//1

julia> g(1/2)
1.0

julia> g(1)
2
```
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`](../../base/numbers/#Base.Rational) literals are less type disruptive than [`Float64`](../../base/numbers/#Core.Float64) literals, but more disruptive than `Int`s:
```julia-repl
julia> h(x) = 2//1 * x
h (generic function with 1 method)

julia> h(1//2)
1//1

julia> h(1/2)
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.
------------------------------------------------------------------------


# Frequently Asked Questions · The Julia Language
Source: https://docs.julialang.org/en/v1/manual/faq/


# [Frequently Asked Questions](#Frequently-Asked-Questions)


## [General](#General)


### [Is Julia named after someone or something?](#Is-Julia-named-after-someone-or-something?)
No.


### [Why don't you compile Matlab/Python/R/… code to Julia?](#Why-don't-you-compile-Matlab/Python/R/…-code-to-Julia?)
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?
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](../performance-tips/#man-performance-tips) 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.


### [Why don't you compile Matlab/Python/R/… code to Julia?](#Why-don't-you-compile-Matlab/Python/R/…-code-to-Julia?)
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.
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.
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](https://github.com/JuliaInterop) packages that connect Julia to Python, Matlab, C++, and more.


## [Public API](#man-api)


### [How does Julia define its public API?](#How-does-Julia-define-its-public-API?)
Julia's public [API](https://en.wikipedia.org/wiki/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.
Public symbols are those marked with either `public foo` or `export foo`.
In other words:
-   Documented behavior of public symbols is part of the public API.
-   Undocumented behavior of public symbols is not part of the public API.
-   Documented behavior of private symbols is not part of the public API.
-   Undocumented behavior of private symbols is not part of the public API.
You can get a complete list of the public symbols from a module with `names(MyModule)`.
Package authors are encouraged to define their public API similarly.
Anything in Julia's Public API is covered by [SemVer](https://semver.org/) and therefore will not be removed or receive meaningful breaking changes before Julia 2.0.


### [There is a useful undocumented function/type/constant. Can I use it?](#There-is-a-useful-undocumented-function/type/constant.-Can-I-use-it?)
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](https://github.com/JuliaLang/julia/issues) or [pull request](https://github.com/JuliaLang/julia/pulls) 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.


### [The documentation is not accurate enough. Can I rely on the existing behavior?](#The-documentation-is-not-accurate-enough.-Can-I-rely-on-the-existing-behavior?)
Please open an [issue](https://github.com/JuliaLang/julia/issues) or [pull request](https://github.com/JuliaLang/julia/pulls) to start a discussion for turning the existing behavior into a public API.


## [Sessions and the REPL](#Sessions-and-the-REPL)


### [How do I delete an object in memory?](#How-do-I-delete-an-object-in-memory?)
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.
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()`](../../base/base/#Base.GC.gc). Moreover, an attempt to use `A` will likely result in an error, because most methods are not defined on type `Nothing`.


### [How can I modify the declaration of a type in my session?](#How-can-I-modify-the-declaration-of-a-type-in-my-session?)
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:
```julia
ERROR: invalid redefinition of constant MyType
```
Types in module `Main` cannot be redefined.
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:
```julia
include("mynewcode.jl")              # this defines a module MyModule
obj1 = MyModule.ObjConstructor(a, b)
obj2 = MyModule.somefunction(obj1)
# Got an error. Change something in "mynewcode.jl"
include("mynewcode.jl")              # reload the module
obj1 = MyModule.ObjConstructor(a, b) # old objects are no longer valid, must reconstruct
obj2 = MyModule.somefunction(obj1)   # this time it worked!
obj3 = MyModule.someotherfunction(obj2, c)
...
```


## [Scripting](#man-scripting)


### [How do I check if the current file is being run as the main script?](#How-do-I-check-if-the-current-file-is-being-run-as-the-main-script?)
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`.
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.


### [How do I catch CTRL-C in a script?](#catch-ctrl-c)
Running a Julia script using `julia file.jl` does not throw [`InterruptException`](../../base/base/#Core.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`](../../base/base/#Base.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`](../../base/base/#try) block. Note that with this strategy [`PROGRAM_FILE`](../../base/constants/#Base.PROGRAM_FILE) will not be set.


### [How do I pass options to julia using #!/usr/bin/env?](#How-do-I-pass-options-to-julia-using-#!/usr/bin/env?)
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:
```julia
#!/usr/bin/env -S julia --color=yes --startup-file=no
@show ARGS  # put any Julia code here
```
Option `env -S` appeared in FreeBSD 6.0 (2005), macOS Sierra (2016) and GNU/Linux coreutils 8.30 (2018).


### [Why doesn't run support * or pipes for scripting external programs?](#Why-doesn't-run-support-*-or-pipes-for-scripting-external-programs?)
Julia's [`run`](../../base/base/#Base.run) function launches external programs *directly*, without invoking an [operating-system shell](https://en.wikipedia.org/wiki/Shell_(computing)) (unlike the `system("...")` function in other languages like Python, R, or C). That means that `run` does not perform wildcard expansion of `*` (["globbing"](https://en.wikipedia.org/wiki/Glob_(programming))), nor does it interpret [shell pipelines](https://en.wikipedia.org/wiki/Pipeline_(Unix)) like `|` or `>`.
You can still do globbing and pipelines using Julia features, however. For example, the built-in [`pipeline`](../../base/base/#Base.pipeline-Tuple%7BAny,%20Any,%20Any,%20Vararg%7BAny%7D%7D) function allows you to chain external programs and files, similar to shell pipes, and the [Glob.jl package](https://github.com/vtjnash/Glob.jl) implements POSIX-compatible globbing.


### [Why doesn't run support * or pipes for scripting external programs?](#Why-doesn't-run-support-*-or-pipes-for-scripting-external-programs?)
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](https://en.wikipedia.org/wiki/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](https://julialang.org/blog/2012/03/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](https://www.python.org/dev/peps/pep-0324/#motivation).)


## [Variables and Assignments](#Variables-and-Assignments)


### [Why am I getting UndefVarError from a simple loop?](#Why-am-I-getting-UndefVarError-from-a-simple-loop?)
You might have something like:
```julia
x = 0
while x < 10
    x += 1
end
```
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**.
Here, `x` is a global variable, `while` defines a [local scope](../variables-and-scoping/#scope-of-variables), and `x += 1` is an assignment to a global in that local scope.
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:
1.  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](../performance-tips/#man-performance-tips).
2.  Wrap the code in a [`let`](../../base/base/#let) block. (This makes `x` a local variable within the `let ... end` statement, again eliminating the need for `global`).


### [Why am I getting UndefVarError from a simple loop?](#Why-am-I-getting-UndefVarError-from-a-simple-loop?)
3.  Explicitly mark `x` as `global` inside the local scope before assigning to it, e.g. write `global x += 1`.
More explanation can be found in the manual section [on soft scope](../variables-and-scoping/#on-soft-scope).


## [Functions](#Functions)


### [I passed an argument x to a function, modified it inside that function, but on the outside, the variable x is still unchanged. Why?](#I-passed-an-argument-x-to-a-function,-modified-it-inside-that-function,-but-on-the-outside,-the-variable-x-is-still-unchanged.-Why?)
Suppose you call a function like this:
```julia-repl
julia> x = 10
10

julia> function change_value!(y)
           y = 17
       end
change_value! (generic function with 1 method)

julia> change_value!(x)
17

julia> x # x is unchanged!
10
```
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.
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:
```julia-repl
julia> x = [1,2,3]
3-element Vector{Int64}:
 1
 2
 3

julia> function change_array!(A)
           A[1] = 5
       end
change_array! (generic function with 1 method)

julia> change_array!(x)
5

julia> x
3-element Vector{Int64}:
 5
 2
 3
```


### [I passed an argument x to a function, modified it inside that function, but on the outside, the variable x is still unchanged. Why?](#I-passed-an-argument-x-to-a-function,-modified-it-inside-that-function,-but-on-the-outside,-the-variable-x-is-still-unchanged.-Why?)
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.


### [Can I use using or import inside a function?](#Can-I-use-using-or-import-inside-a-function?)
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:
1.  Use `import`:
    ```julia
    import Foo
    function bar(...)
        # ... refer to Foo symbols via Foo.baz ...
    end
    ```
    This 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.
2.  Wrap your function in a module:
    ```julia
    module Bar
    export bar
    using Foo
    function bar(...)
        # ... refer to Foo.baz as simply baz ....
    end
    end
    using Bar
    ```
    This imports all the symbols from `Foo`, but only inside the module `Bar`.


### [What does the ... operator do?](#What-does-the-...-operator-do?)


#### [The two uses of the ... operator: slurping and splatting](#The-two-uses-of-the-...-operator:-slurping-and-splatting)
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.


#### [... combines many arguments into one argument in function definitions](#...-combines-many-arguments-into-one-argument-in-function-definitions)
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:
```julia-repl
julia> function printargs(args...)
           println(typeof(args))
           for (i, arg) in enumerate(args)
               println("Arg #$i = $arg")
           end
       end
printargs (generic function with 1 method)

julia> printargs(1, 2, 3)
Tuple{Int64, Int64, Int64}
Arg #1 = 1
Arg #2 = 2
Arg #3 = 3
```
If Julia were a language that made more liberal use of ASCII characters, the slurping operator might have been written as `<-...` instead of `...`.


#### [... splits one argument into many different arguments in function calls](#...-splits-one-argument-into-many-different-arguments-in-function-calls)
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:
```julia-repl
julia> function threeargs(a, b, c)
           println("a = $a::$(typeof(a))")
           println("b = $b::$(typeof(b))")
           println("c = $c::$(typeof(c))")
       end
threeargs (generic function with 1 method)

julia> x = [1, 2, 3]
3-element Vector{Int64}:
 1
 2
 3

julia> threeargs(x...)
a = 1::Int64
b = 2::Int64
c = 3::Int64
```
If Julia were a language that made more liberal use of ASCII characters, the splatting operator might have been written as `...->` instead of `...`.


### [What is the return value of an assignment?](#What-is-the-return-value-of-an-assignment?)
The operator `=` always returns the right-hand side, therefore:
```julia-repl
julia> function threeint()
           x::Int = 3.0
           x # returns variable x
       end
threeint (generic function with 1 method)

julia> function threefloat()
           x::Int = 3.0 # returns 3.0
       end
threefloat (generic function with 1 method)

julia> threeint()
3

julia> threefloat()
3.0
```
and similarly:
```julia-repl
julia> function twothreetup()
           x, y = [2, 3] # assigns 2 to x and 3 to y
           x, y # returns a tuple
       end
twothreetup (generic function with 1 method)

julia> function twothreearr()
           x, y = [2, 3] # returns an array
       end
twothreearr (generic function with 1 method)

julia> twothreetup()
(2, 3)

julia> twothreearr()
2-element Vector{Int64}:
 2
 3
```


## [Types, type declarations, and constructors](#Types,-type-declarations,-and-constructors)


### [What does "type-stable" mean?](#man-type-stability)
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:
```julia-repl
julia> function unstable(flag::Bool)
           if flag
               return 1
           else
               return 1.0
           end
       end
unstable (generic function with 1 method)
```
It returns either an `Int` or a [`Float64`](../../base/numbers/#Core.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.


### [Why does Julia give a DomainError for certain seemingly-sensible operations?](#faq-domain-errors)
Certain operations make mathematical sense but result in errors:
```julia-repl
julia> sqrt(-2.0)
ERROR: DomainError with -2.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:
[...]
```
This behavior is an inconvenient consequence of the requirement for type-stability. In the case of [`sqrt`](../../base/math/#Base.sqrt-Tuple%7BNumber%7D), 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`](../../base/math/#Base.sqrt-Tuple%7BNumber%7D) function to switch to a complex-valued output only when passed a negative number (which is what [`sqrt`](../../base/math/#Base.sqrt-Tuple%7BNumber%7D) does in some other languages), but then the result would not be [type-stable](#man-type-stability) and the [`sqrt`](../../base/math/#Base.sqrt-Tuple%7BNumber%7D) function would have poor performance.
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:
```julia-repl
julia> sqrt(-2.0+0im)
0.0 + 1.4142135623730951im
```


### [How can I constrain or compute type parameters?](#How-can-I-constrain-or-compute-type-parameters?)
The parameters of a [parametric type](../types/#Parametric-Types) 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 ([`<:`](../../base/base/#Core.:%3C:)) 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`](../../base/base/#Core.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](../constructors/#man-constructors).
As an example, consider
```julia
struct ConstrainedType{T,N,N+1} # NOTE: INVALID SYNTAX
    A::Array{T,N}
    B::Array{T,N+1}
end
```


### [How can I constrain or compute type parameters?](#How-can-I-constrain-or-compute-type-parameters?)
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](../constructors/#man-inner-constructor-methods) (where it can be combined with other checks):
```julia
struct ConstrainedType{T,N,M}
    A::Array{T,N}
    B::Array{T,M}
    function ConstrainedType(A::Array{T,N}, B::Array{T,M}) where {T,N,M}
        N + 1 == M || throw(ArgumentError("second argument should have one more axis" ))
        new{T,N,M}(A, B)
    end
end
```
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](../constructors/#man-outer-constructor-methods) that performs this calculation:
```julia
ConstrainedType(A) = ConstrainedType(A, compute_B(A))
```


### [Why does Julia use native machine integer arithmetic?](#faq-integer-arithmetic)
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:
```julia-repl
julia> x = typemax(Int)
9223372036854775807

julia> y = x+1
-9223372036854775808

julia> z = -y
-9223372036854775808

julia> 2*z
0
```
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.


### [Why does Julia use native machine integer arithmetic?](#faq-integer-arithmetic)
One alternative to consider would be to check each integer operation for overflow and promote results to bigger integer types such as [`Int128`](../../base/numbers/#Core.Int128) or [`BigInt`](../../base/numbers/#Base.GMP.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](#man-type-stability) 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.


### [Why does Julia use native machine integer arithmetic?](#faq-integer-arithmetic)
A variation on this approach, which avoids the appearance of type instability is to merge the `Int` and [`BigInt`](../../base/numbers/#Base.GMP.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.


### [Why does Julia use native machine integer arithmetic?](#faq-integer-arithmetic)
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:
```julia
>> int64(9223372036854775807)

ans =

  9223372036854775807

>> int64(9223372036854775807) + 1

ans =

  9223372036854775807

>> int64(-9223372036854775808)

ans =

 -9223372036854775808

>> int64(-9223372036854775808) - 1

ans =

 -9223372036854775808
```
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)`](../../base/base/#Base.typemin) or [`typemax(Int)`](../../base/base/#Base.typemax) 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:


### [Why does Julia use native machine integer arithmetic?](#faq-integer-arithmetic)
```julia
>> n = int64(2)^62
4611686018427387904

>> n + (n - 1)
9223372036854775807

>> (n + n) - 1
9223372036854775806
```
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`:
```julia-repl
julia> n = 2^62
4611686018427387904

julia> (n + 2n) >>> 1
6917529027641081856
```
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:
```julia
>> (n + 2*n)/2

ans =

  4611686018427387904
```
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.
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:
```julia-repl
julia> code_native(f, Tuple{Int})
  .text
Filename: none
  pushq %rbp
  movq  %rsp, %rbp
Source line: 1
  leaq  -1(%rdi,%rdi,4), %rax
  popq  %rbp
  retq
  nopl  (%rax,%rax)
```


### [Why does Julia use native machine integer arithmetic?](#faq-integer-arithmetic)
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:
```julia-repl
julia> function g(k, n)
           for i = 1:n
               k = f(k)
           end
           return k
       end
g (generic function with 1 methods)

julia> code_native(g, Tuple{Int,Int})
  .text
Filename: none
  pushq %rbp
  movq  %rsp, %rbp
Source line: 2
  testq %rsi, %rsi
  jle L26
  nopl  (%rax)
Source line: 3
L16:
  leaq  -1(%rdi,%rdi,4), %rdi
Source line: 2
  decq  %rsi
  jne L16
Source line: 5
L26:
  movq  %rdi, %rax
  popq  %rbp
  retq
  nop
```
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:
```julia-repl
julia> function g(k)
           for i = 1:10
               k = f(k)
           end
           return k
       end
g (generic function with 2 methods)

julia> code_native(g,(Int,))
  .text
Filename: none
  pushq %rbp
  movq  %rsp, %rbp
Source line: 3
  imulq $9765625, %rdi, %rax    # imm = 0x9502F9
  addq  $-2441406, %rax         # imm = 0xFFDABF42
Source line: 5
  popq  %rbp
  retq
  nopw  %cs:(%rax,%rax)
```


### [Why does Julia use native machine integer arithmetic?](#faq-integer-arithmetic)
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.
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](https://danluu.com/integer-overflow/), 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.


### [Why does Julia use native machine integer arithmetic?](#faq-integer-arithmetic)
In the meantime, overflow-safe integer operations can be achieved through the use of external libraries such as [SaferIntegers.jl](https://github.com/JeffreySarnoff/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](https://github.com/JuliaLang/julia/issues/855).