## [Advanced Usage](#Advanced-Usage)
The `@doc` macro associates its first argument with its second in a per-module dictionary called `META`.
To make it easier to write documentation, the parser treats the macro name `@doc` specially: if a call to `@doc` has one argument, but another expression appears after a single line break, then that additional expression is added as an argument to the macro. Therefore the following syntax is parsed as a 2-argument call to `@doc`:
```julia
@doc raw"""
...
"""
f(x) = x
```
This makes it possible to use expressions other than normal string literals (such as the `raw""` string macro) as a docstring.
When used for retrieving documentation, the `@doc` macro (or equally, the `doc` function) will search all `META` dictionaries for metadata relevant to the given object and return it. The returned object (some Markdown content, for example) will by default display itself intelligently. This design also makes it easy to use the doc system in a programmatic way; for example, to re-use documentation between different versions of a function:
```julia
@doc "..." foo!
@doc (@doc foo!) foo
```
Or for use with Julia's metaprogramming functionality:
```julia
for (f, op) in ((:add, :+), (:subtract, :-), (:multiply, :*), (:divide, :/))
    @eval begin
        $f(a, b) = $op(a, b)
    end
end
@doc "`add(a, b)` adds `a` and `b` together" add
@doc "`subtract(a, b)` subtracts `b` from `a`" subtract
```


## [Advanced Usage](#Advanced-Usage)
Documentation in non-toplevel blocks, such as `begin`, `if`, `for`, `let`, and inner constructors, should be added to the documentation system via `@doc` as well. For example:
```julia
if condition()
    @doc "..."
    f(x) = x
end
```
will add documentation to `f(x)` when `condition()` is `true`. Note that even if `f(x)` goes out of scope at the end of a block, its documentation will remain.
It is possible to make use of metaprogramming to assist in the creation of documentation. When using string-interpolation within the docstring you will need to use an extra `$` as shown with `$($name)`:
```julia
for func in (:day, :dayofmonth)
    name = string(func)
    @eval begin
        @doc """
            $($name)(dt::TimeType) -> Int64

        The day of month of a `Date` or `DateTime` as an `Int64`.
        """ $func(dt::Dates.TimeType)
    end
end
```


### [Dynamic documentation](#Dynamic-documentation)
Sometimes the appropriate documentation for an instance of a type depends on the field values of that instance, rather than just on the type itself. In these cases, you can add a method to `Docs.getdoc` for your custom type that returns the documentation on a per-instance basis. For instance,
```julia
struct MyType
    value::Int
end

Docs.getdoc(t::MyType) = "Documentation for MyType with value $(t.value)"

x = MyType(1)
y = MyType(2)
```
`?x` will display "Documentation for MyType with value 1" while `?y` will display "Documentation for MyType with value 2".


## [Syntax Guide](#Syntax-Guide)
This guide provides a comprehensive overview of how to attach documentation to all Julia syntax constructs for which providing documentation is possible.
In the following examples `"..."` is used to illustrate an arbitrary docstring.


### [$ and \ characters](#and-\\-characters)
The `$` and `\` characters are still parsed as string interpolation or start of an escape sequence in docstrings too. The `raw""` string macro together with the `@doc` macro can be used to avoid having to escape them. This is handy when the docstrings include LaTeX or Julia source code examples containing interpolation:
````julia
@doc raw"""
```math
\LaTeX
```
"""
function f end
````


### [Functions and Methods](#Functions-and-Methods-2)
```julia
"..."
function f end

"..."
f
```
Adds docstring `"..."` to the function `f`. The first version is the preferred syntax, however both are equivalent.
```julia
"..."
f(x) = x

"..."
function f(x)
    return x
end

"..."
f(x)
```
Adds docstring `"..."` to the method `f(::Any)`.
```julia
"..."
f(x, y = 1) = x + y
```
Adds docstring `"..."` to two `Method`s, namely `f(::Any)` and `f(::Any, ::Any)`.


### [Macros](#Macros)
```julia
"..."
macro m(x) end
```
Adds docstring `"..."` to the `@m(::Any)` macro definition.
```julia
"..."
:(@m1)

"..."
macro m2 end
```
Adds docstring `"..."` to the macros named `@m1` and `@m2`.


### [Types](#Types)
```julia
"..."
abstract type T1 end

"..."
mutable struct T2
    ...
end

"..."
struct T3
    ...
end
```
Adds the docstring `"..."` to types `T1`, `T2`, and `T3`.
```julia
"..."
T1

"..."
T2

"..."
T3
```
Adds the docstring `"..."` to types `T1`, `T2`, and `T3`. The previous version is the preferred syntax, however both are equivalent.
```julia
"..."
struct T
    "x"
    x
    "y"
    y

    @doc "Inner constructor"
    function T()
        new(...)
    end
end
```
Adds docstring `"..."` to type `T`, `"x"` to field `T.x`, `"y"` to field `T.y`, and `"Inner constructor"` to the inner constructor `T()`. Also applicable to `mutable struct` types.


### [Modules](#Modules)
```julia
"..."
module M end

module M

"..."
M

end
```
Adds docstring `"..."` to the `Module` `M`. Adding the docstring above the `Module` is the preferred syntax, however both are equivalent.
```julia
"..."
baremodule M
# ...
end

baremodule M

import Base: @doc

"..."
f(x) = x

end
```
Documenting a `baremodule` by placing a docstring above the expression automatically imports `@doc` into the module. These imports must be done manually when the module expression is not documented.


### [Global Variables](#Global-Variables)
```julia
"..."
const a = 1

"..."
b = 2

"..."
global c = 3
```
Adds docstring `"..."` to the `Binding`s `a`, `b`, and `c`.
`Binding`s are used to store a reference to a particular `Symbol` in a `Module` without storing the referenced value itself.
When a `const` definition is only used to define an alias of another definition, such as is the case with the function `div` and its alias `÷` in `Base`, do not document the alias and instead document the actual function.
If the alias is documented and not the real definition then the docsystem (`?` mode) will not return the docstring attached to the alias when the real definition is searched for.
For example you should write
```julia
"..."
f(x) = x + 1
const alias = f
```
rather than
```julia
f(x) = x + 1
"..."
const alias = f
```
```julia
"..."
sym
```
Adds docstring `"..."` to the value associated with `sym`. However, it is preferred that `sym` is documented where it is defined.


### [Multiple Objects](#Multiple-Objects)
```julia
"..."
a, b
```
Adds docstring `"..."` to `a` and `b` each of which should be a documentable expression. This syntax is equivalent to
```julia
"..."
a

"..."
b
```
Any number of expressions many be documented together in this way. This syntax can be useful when two functions are related, such as non-mutating and mutating versions `f` and `f!`.


### [Macro-generated code](#Macro-generated-code)
```julia
"..."
@m expression
```
Adds docstring `"..."` to the expression generated by expanding `@m expression`. This allows for expressions decorated with `@inline`, `@noinline`, `@generated`, or any other macro to be documented in the same way as undecorated expressions.
Macro authors should take note that only macros that generate a single expression will automatically support docstrings. If a macro returns a block containing multiple subexpressions then the subexpression that should be documented must be marked using the [`@__doc__`](#Core.@__doc__) macro.
The [`@enum`](../../base/base/#Base.Enums.@enum) macro makes use of `@__doc__` to allow for documenting [`Enum`](../../base/base/#Base.Enums.Enum)s. Examining its definition should serve as an example of how to use `@__doc__` correctly.
```julia
@__doc__(ex)
```
Low-level macro used to mark expressions returned by a macro that should be documented. If more than one expression is marked then the same docstring is applied to each expression.
```julia
macro example(f)
    quote
        $(f)() = 0
        @__doc__ $(f)(x) = 1
        $(f)(x, y) = 2
    end |> esc
end
```
`@__doc__` has no effect when a macro that uses it is not documented.
[source](https://github.com/JuliaLang/julia/blob/9615af0f269df4d371b8010e9507ed5bae86103b/base/docs/Docs.jl#L434-L449)
------------------------------------------------------------------------


# Metaprogramming · The Julia Language
Source: https://docs.julialang.org/en/v1/manual/metaprogramming/


# [Metaprogramming](#Metaprogramming)
The strongest legacy of Lisp in the Julia language is its metaprogramming support. Like Lisp, Julia represents its own code as a data structure of the language itself. Since code is represented by objects that can be created and manipulated from within the language, it is possible for a program to transform and generate its own code. This allows sophisticated code generation without extra build steps, and also allows true Lisp-style macros operating at the level of [abstract syntax trees](https://en.wikipedia.org/wiki/Abstract_syntax_tree). In contrast, preprocessor "macro" systems, like that of C and C++, perform textual manipulation and substitution before any actual parsing or interpretation occurs. Because all data types and code in Julia are represented by Julia data structures, powerful [reflection](https://en.wikipedia.org/wiki/Reflection_%28computer_programming%29) capabilities are available to explore the internals of a program and its types just like any other data.
Metaprogramming is a powerful tool, but it introduces complexity that can make code more difficult to understand. For example, it can be surprisingly hard to get scope rules correct. Metaprogramming should typically be used only when other approaches such as [higher order functions](../functions/#man-anonymous-functions) and [closures](https://en.wikipedia.org/wiki/Closure_(computer_programming)) cannot be applied.


# [Metaprogramming](#Metaprogramming)
`eval` and defining new macros should be typically used as a last resort. It is almost never a good idea to use `Meta.parse` or convert an arbitrary string into Julia code. For manipulating Julia code, use the `Expr` data structure directly to avoid the complexity of how Julia syntax is parsed.
The best uses of metaprogramming often implement most of their functionality in runtime helper functions, striving to minimize the amount of code they generate.


## [Program representation](#Program-representation)
Every Julia program starts life as a string:
```julia-repl
julia> prog = "1 + 1"
"1 + 1"
```
**What happens next?**
The next step is to [parse](https://en.wikipedia.org/wiki/Parsing#Computer_languages) each string into an object called an expression, represented by the Julia type [`Expr`](../../base/base/#Core.Expr):
```julia-repl
julia> ex1 = Meta.parse(prog)
:(1 + 1)

julia> typeof(ex1)
Expr
```
`Expr` objects contain two parts:
-   a [`Symbol`](../../base/base/#Core.Symbol) identifying the kind of expression. A symbol is an [interned string](https://en.wikipedia.org/wiki/String_interning) identifier (more discussion below).
```julia-repl
julia> ex1.head
:call
```
-   the expression arguments, which may be symbols, other expressions, or literal values:
```julia-repl
julia> ex1.args
3-element Vector{Any}:
  :+
 1
 1
```
Expressions may also be constructed directly in [prefix notation](https://en.wikipedia.org/wiki/Polish_notation):
```julia-repl
julia> ex2 = Expr(:call, :+, 1, 1)
:(1 + 1)
```
The two expressions constructed above – by parsing and by direct construction – are equivalent:
```julia-repl
julia> ex1 == ex2
true
```
**The key point here is that Julia code is internally represented as a data structure that is accessible from the language itself.**
The [`dump`](../../base/io-network/#Base.dump) function provides indented and annotated display of `Expr` objects:
```julia-repl
julia> dump(ex2)
Expr
  head: Symbol call
  args: Array{Any}((3,))
    1: Symbol +
    2: Int64 1
    3: Int64 1
```


## [Program representation](#Program-representation)
`Expr` objects may also be nested:
```julia-repl
julia> ex3 = Meta.parse("(4 + 4) / 2")
:((4 + 4) / 2)
```
Another way to view expressions is with `Meta.show_sexpr`, which displays the [S-expression](https://en.wikipedia.org/wiki/S-expression) form of a given `Expr`, which may look very familiar to users of Lisp. Here's an example illustrating the display on a nested `Expr`:
```julia-repl
julia> Meta.show_sexpr(ex3)
(:call, :/, (:call, :+, 4, 4), 2)
```


### [Symbols](#Symbols)
The `:` character has two syntactic purposes in Julia. The first form creates a [`Symbol`](../../base/base/#Core.Symbol), an [interned string](https://en.wikipedia.org/wiki/String_interning) used as one building-block of expressions, from valid identifiers:
```julia-repl
julia> s = :foo
:foo

julia> typeof(s)
Symbol
```
The [`Symbol`](../../base/base/#Core.Symbol) constructor takes any number of arguments and creates a new symbol by concatenating their string representations together:
```julia-repl
julia> :foo === Symbol("foo")
true

julia> Symbol("1foo") # `:1foo` would not work, as `1foo` is not a valid identifier
Symbol("1foo")

julia> Symbol("func",10)
:func10

julia> Symbol(:var,'_',"sym")
:var_sym
```
In the context of an expression, symbols are used to indicate access to variables; when an expression is evaluated, a symbol is replaced with the value bound to that symbol in the appropriate [scope](../variables-and-scoping/#scope-of-variables).
Sometimes extra parentheses around the argument to `:` are needed to avoid ambiguity in parsing:
```julia-repl
julia> :(:)
:(:)

julia> :(::)
:(::)
```


## [Expressions and evaluation](#Expressions-and-evaluation)


### [Quoting](#Quoting)
The second syntactic purpose of the `:` character is to create expression objects without using the explicit [`Expr`](../../base/base/#Core.Expr) constructor. This is referred to as *quoting*. The `:` character, followed by paired parentheses around a single statement of Julia code, produces an `Expr` object based on the enclosed code. Here is an example of the short form used to quote an arithmetic expression:
```julia-repl
julia> ex = :(a+b*c+1)
:(a + b * c + 1)

julia> typeof(ex)
Expr
```
(to view the structure of this expression, try `ex.head` and `ex.args`, or use [`dump`](../../base/io-network/#Base.dump) as above or [`Meta.@dump`](../../base/io-network/#Base.Meta.@dump))
Note that equivalent expressions may be constructed using [`Meta.parse`](../../base/base/#Base.Meta.parse-Tuple%7BAbstractString,%20Int64%7D) or the direct `Expr` form:
```julia-repl
julia>      :(a + b*c + 1)       ==
       Meta.parse("a + b*c + 1") ==
       Expr(:call, :+, :a, Expr(:call, :*, :b, :c), 1)
true
```
Expressions provided by the parser generally only have symbols, other expressions, and literal values as their args, whereas expressions constructed by Julia code can have arbitrary run-time values without literal forms as args. In this specific example, `+` and `a` are symbols, `*(b,c)` is a subexpression, and `1` is a literal 64-bit signed integer.
There is a second syntactic form of quoting for multiple expressions: blocks of code enclosed in `quote ... end`.


### [Quoting](#Quoting)
```julia-repl
julia> ex = quote
           x = 1
           y = 2
           x + y
       end
quote
    #= none:2 =#
    x = 1
    #= none:3 =#
    y = 2
    #= none:4 =#
    x + y
end

julia> typeof(ex)
Expr
```


### [Interpolation](#man-expression-interpolation)
Direct construction of [`Expr`](../../base/base/#Core.Expr) objects with value arguments is powerful, but `Expr` constructors can be tedious compared to "normal" Julia syntax. As an alternative, Julia allows *interpolation* of literals or expressions into quoted expressions. Interpolation is indicated by a prefix `$`.
In this example, the value of variable `a` is interpolated:
```julia-repl
julia> a = 1;

julia> ex = :($a + b)
:(1 + b)
```
Interpolating into an unquoted expression is not supported and will cause a compile-time error:
```julia-repl
julia> $a + b
ERROR: syntax: "$" expression outside quote
```
In this example, the tuple `(1,2,3)` is interpolated as an expression into a conditional test:
```julia-repl
julia> ex = :(a in $:((1,2,3)) )
:(a in (1, 2, 3))
```
The use of `$` for expression interpolation is intentionally reminiscent of [string interpolation](../strings/#string-interpolation) and [command interpolation](../running-external-programs/#command-interpolation). Expression interpolation allows convenient, readable programmatic construction of complex Julia expressions.


### [Splatting interpolation](#Splatting-interpolation)
Notice that the `$` interpolation syntax allows inserting only a single expression into an enclosing expression. Occasionally, you have an array of expressions and need them all to become arguments of the surrounding expression. This can be done with the syntax `$(xs...)`. For example, the following code generates a function call where the number of arguments is determined programmatically:
```julia-repl
julia> args = [:x, :y, :z];

julia> :(f(1, $(args...)))
:(f(1, x, y, z))
```


### [Nested quote](#Nested-quote)
Naturally, it is possible for quote expressions to contain other quote expressions. Understanding how interpolation works in these cases can be a bit tricky. Consider this example:
```julia-repl
julia> x = :(1 + 2);

julia> e = quote quote $x end end
quote
    #= none:1 =#
    $(Expr(:quote, quote
    #= none:1 =#
    $(Expr(:$, :x))
end))
end
```
Notice that the result contains `$x`, which means that `x` has not been evaluated yet. In other words, the `$` expression "belongs to" the inner quote expression, and so its argument is only evaluated when the inner quote expression is:
```julia-repl
julia> eval(e)
quote
    #= none:1 =#
    1 + 2
end
```
However, the outer `quote` expression is able to interpolate values inside the `$` in the inner quote. This is done with multiple `$`s:
```julia-repl
julia> e = quote quote $$x end end
quote
    #= none:1 =#
    $(Expr(:quote, quote
    #= none:1 =#
    $(Expr(:$, :(1 + 2)))
end))
end
```
Notice that `(1 + 2)` now appears in the result instead of the symbol `x`. Evaluating this expression yields an interpolated `3`:
```julia-repl
julia> eval(e)
quote
    #= none:1 =#
    3
end
```
The intuition behind this behavior is that `x` is evaluated once for each `$`: one `$` works similarly to `eval(:x)`, giving `x`'s value, while two `$`s do the equivalent of `eval(eval(:x))`.


### [QuoteNode](#man-quote-node)
The usual representation of a `quote` form in an AST is an [`Expr`](../../base/base/#Core.Expr) with head `:quote`:
```julia-repl
julia> dump(Meta.parse(":(1+2)"))
Expr
  head: Symbol quote
  args: Array{Any}((1,))
    1: Expr
      head: Symbol call
      args: Array{Any}((3,))
        1: Symbol +
        2: Int64 1
        3: Int64 2
```
As we have seen, such expressions support interpolation with `$`. However, in some situations it is necessary to quote code *without* performing interpolation. This kind of quoting does not yet have syntax, but is represented internally as an object of type `QuoteNode`:
```julia-repl
julia> eval(Meta.quot(Expr(:$, :(1+2))))
3

julia> eval(QuoteNode(Expr(:$, :(1+2))))
:($(Expr(:$, :(1 + 2))))
```
The parser yields `QuoteNode`s for simple quoted items like symbols:
```julia-repl
julia> dump(Meta.parse(":x"))
QuoteNode
  value: Symbol x
```
`QuoteNode` can also be used for certain advanced metaprogramming tasks.


### [Evaluating expressions](#Evaluating-expressions)
Given an expression object, one can cause Julia to evaluate (execute) it at global scope using [`eval`](../../base/base/#eval):
```julia-repl
julia> ex1 = :(1 + 2)
:(1 + 2)

julia> eval(ex1)
3

julia> ex = :(a + b)
:(a + b)

julia> eval(ex)
ERROR: UndefVarError: `b` not defined in `Main`
[...]

julia> a = 1; b = 2;

julia> eval(ex)
3
```
Every [module](../modules/#modules) has its own [`eval`](../../base/base/#eval) function that evaluates expressions in its global scope. Expressions passed to [`eval`](../../base/base/#eval) are not limited to returning values – they can also have side-effects that alter the state of the enclosing module's environment:
```julia-repl
julia> ex = :(x = 1)
:(x = 1)

julia> x
ERROR: UndefVarError: `x` not defined in `Main`

julia> eval(ex)
1

julia> x
1
```
Here, the evaluation of an expression object causes a value to be assigned to the global variable `x`.
Since expressions are just `Expr` objects which can be constructed programmatically and then evaluated, it is possible to dynamically generate arbitrary code which can then be run using [`eval`](../../base/base/#eval). Here is a simple example:
```julia-repl
julia> a = 1;

julia> ex = Expr(:call, :+, a, :b)
:(1 + b)

julia> a = 0; b = 2;

julia> eval(ex)
3
```
The value of `a` is used to construct the expression `ex` which applies the `+` function to the value 1 and the variable `b`. Note the important distinction between the way `a` and `b` are used:


### [Evaluating expressions](#Evaluating-expressions)
-   The value of the *variable* `a` at expression construction time is used as an immediate value in the expression. Thus, the value of `a` when the expression is evaluated no longer matters: the value in the expression is already `1`, independent of whatever the value of `a` might be.
-   On the other hand, the *symbol* `:b` is used in the expression construction, so the value of the variable `b` at that time is irrelevant – `:b` is just a symbol and the variable `b` need not even be defined. At expression evaluation time, however, the value of the symbol `:b` is resolved by looking up the value of the variable `b`.


### [Functions on Expressions](#Functions-on-Expressions)
As hinted above, one extremely useful feature of Julia is the capability to generate and manipulate Julia code within Julia itself. We have already seen one example of a function returning [`Expr`](../../base/base/#Core.Expr) objects: the [`Meta.parse`](../../base/base/#Base.Meta.parse-Tuple%7BAbstractString,%20Int64%7D) function, which takes a string of Julia code and returns the corresponding `Expr`. A function can also take one or more `Expr` objects as arguments, and return another `Expr`. Here is a simple, motivating example:
```julia-repl
julia> function math_expr(op, op1, op2)
           expr = Expr(:call, op, op1, op2)
           return expr
       end
math_expr (generic function with 1 method)

julia>  ex = math_expr(:+, 1, Expr(:call, :*, 4, 5))
:(1 + 4 * 5)

julia> eval(ex)
21
```
As another example, here is a function that doubles any numeric argument, but leaves expressions alone:
```julia-repl
julia> function make_expr2(op, opr1, opr2)
           opr1f, opr2f = map(x -> isa(x, Number) ? 2*x : x, (opr1, opr2))
           retexpr = Expr(:call, op, opr1f, opr2f)
           return retexpr
       end
make_expr2 (generic function with 1 method)

julia> make_expr2(:+, 1, 2)
:(2 + 4)

julia> ex = make_expr2(:+, 1, Expr(:call, :*, 5, 8))
:(2 + 5 * 8)

julia> eval(ex)
42
```


## [Macros](#man-macros)
Macros provide a mechanism to include generated code in the final body of a program. A macro maps a tuple of arguments to a returned *expression*, and the resulting expression is compiled directly rather than requiring a runtime [`eval`](../../base/base/#eval) call. Macro arguments may include expressions, literal values, and symbols.


### [Basics](#Basics)
Here is an extraordinarily simple macro:
```julia-repl
julia> macro sayhello()
           return :( println("Hello, world!") )
       end
@sayhello (macro with 1 method)
```
Macros have a dedicated character in Julia's syntax: the `@` (at-sign), followed by the unique name declared in a `macro NAME ... end` block. In this example, the compiler will replace all instances of `@sayhello` with:
```julia
:( println("Hello, world!") )
```
When `@sayhello` is entered in the REPL, the expression executes immediately, thus we only see the evaluation result:
```julia-repl
julia> @sayhello()
Hello, world!
```
Now, consider a slightly more complex macro:
```julia-repl
julia> macro sayhello(name)
           return :( println("Hello, ", $name) )
       end
@sayhello (macro with 1 method)
```
This macro takes one argument: `name`. When `@sayhello` is encountered, the quoted expression is *expanded* to interpolate the value of the argument into the final expression:
```julia-repl
julia> @sayhello("human")
Hello, human
```
We can view the quoted return expression using the function [`macroexpand`](../../base/base/#Base.macroexpand) (**important note:** this is an extremely useful tool for debugging macros):
```julia-repl
julia> ex = macroexpand(Main, :(@sayhello("human")) )
:(Main.println("Hello, ", "human"))

julia> typeof(ex)
Expr
```
We can see that the `"human"` literal has been interpolated into the expression.
There also exists a macro [`@macroexpand`](../../base/base/#Base.@macroexpand) that is perhaps a bit more convenient than the `macroexpand` function:


### [Basics](#Basics)
```julia-repl
julia> @macroexpand @sayhello "human"
:(println("Hello, ", "human"))
```


### [Hold up: why macros?](#Hold-up:-why-macros?)
We have already seen a function `f(::Expr...) -> Expr` in a previous section. In fact, [`macroexpand`](../../base/base/#Base.macroexpand) is also such a function. So, why do macros exist?
Macros are necessary because they execute when code is parsed, therefore, macros allow the programmer to generate and include fragments of customized code *before* the full program is run. To illustrate the difference, consider the following example:
```julia-repl
julia> macro twostep(arg)
           println("I execute at parse time. The argument is: ", arg)
           return :(println("I execute at runtime. The argument is: ", $arg))
       end
@twostep (macro with 1 method)

julia> ex = macroexpand(Main, :(@twostep :(1, 2, 3)) );
I execute at parse time. The argument is: :((1, 2, 3))
```
The first call to [`println`](../../base/io-network/#Base.println) is executed when [`macroexpand`](../../base/base/#Base.macroexpand) is called. The resulting expression contains *only* the second `println`:
```julia-repl
julia> typeof(ex)
Expr

julia> ex
:(println("I execute at runtime. The argument is: ", $(Expr(:copyast, :($(QuoteNode(:((1, 2, 3)))))))))

julia> eval(ex)
I execute at runtime. The argument is: (1, 2, 3)
```


### [Macro invocation](#Macro-invocation)
Macros are invoked with the following general syntax:
```julia
@name expr1 expr2 ...
@name(expr1, expr2, ...)
```
Note the distinguishing `@` before the macro name and the lack of commas between the argument expressions in the first form, and the lack of whitespace after `@name` in the second form. The two styles should not be mixed. For example, the following syntax is different from the examples above; it passes the tuple `(expr1, expr2, ...)` as one argument to the macro:
```julia
@name (expr1, expr2, ...)
```
An alternative way to invoke a macro over an array literal (or comprehension) is to juxtapose both without using parentheses. In this case, the array will be the only expression fed to the macro. The following syntax is equivalent (and different from `@name [a b] * v`):
```julia
@name[a b] * v
@name([a b]) * v
```
It is important to emphasize that macros receive their arguments as expressions, literals, or symbols. One way to explore macro arguments is to call the [`show`](../../base/io-network/#Base.show-Tuple%7BIO,%20Any%7D) function within the macro body:


### [Macro invocation](#Macro-invocation)
```julia-repl
julia> macro showarg(x)
           show(x)
           # ... remainder of macro, returning an expression
       end
@showarg (macro with 1 method)

julia> @showarg(a)
:a

julia> @showarg(1+1)
:(1 + 1)

julia> @showarg(println("Yo!"))
:(println("Yo!"))

julia> @showarg(1)        # Numeric literal
1

julia> @showarg("Yo!")    # String literal
"Yo!"

julia> @showarg("Yo! $("hello")")    # String with interpolation is an Expr rather than a String
:("Yo! $("hello")")
```
In addition to the given argument list, every macro is passed extra arguments named `__source__` and `__module__`.
The argument `__source__` provides information (in the form of a `LineNumberNode` object) about the parser location of the `@` sign from the macro invocation. This allows macros to include better error diagnostic information, and is commonly used by logging, string-parser macros, and docs, for example, as well as to implement the [`@__LINE__`](../../base/base/#Base.@__LINE__), [`@__FILE__`](../../base/base/#Base.@__FILE__), and [`@__DIR__`](../../base/base/#Base.@__DIR__) macros.
The location information can be accessed by referencing `__source__.line` and `__source__.file`:
```julia-repl
julia> macro __LOCATION__(); return QuoteNode(__source__); end
@__LOCATION__ (macro with 1 method)

julia> dump(
            @__LOCATION__(
       ))
LineNumberNode
  line: Int64 2
  file: Symbol none
```


### [Macro invocation](#Macro-invocation)
The argument `__module__` provides information (in the form of a `Module` object) about the expansion context of the macro invocation. This allows macros to look up contextual information, such as existing bindings, or to insert the value as an extra argument to a runtime function call doing self-reflection in the current module.


### [Building an advanced macro](#Building-an-advanced-macro)
Here is a simplified definition of Julia's [`@assert`](../../base/base/#Base.@assert) macro:
```julia-repl
julia> macro assert(ex)
           return :( $ex ? nothing : throw(AssertionError($(string(ex)))) )
       end
@assert (macro with 1 method)
```
This macro can be used like this:
```julia-repl
julia> @assert 1 == 1.0

julia> @assert 1 == 0
ERROR: AssertionError: 1 == 0
```
In place of the written syntax, the macro call is expanded at parse time to its returned result. This is equivalent to writing:
```julia
1 == 1.0 ? nothing : throw(AssertionError("1 == 1.0"))
1 == 0 ? nothing : throw(AssertionError("1 == 0"))
```
That is, in the first call, the expression `:(1 == 1.0)` is spliced into the test condition slot, while the value of `string(:(1 == 1.0))` is spliced into the assertion message slot. The entire expression, thus constructed, is placed into the syntax tree where the `@assert` macro call occurs. Then at execution time, if the test expression evaluates to true, then [`nothing`](../../base/constants/#Core.nothing) is returned, whereas if the test is false, an error is raised indicating the asserted expression that was false. Notice that it would not be possible to write this as a function, since only the *value* of the condition is available and it would be impossible to display the expression that computed it in the error message.


### [Building an advanced macro](#Building-an-advanced-macro)
The actual definition of `@assert` in Julia Base is more complicated. It allows the user to optionally specify their own error message, instead of just printing the failed expression. Just like in functions with a variable number of arguments ([Varargs Functions](../functions/#Varargs-Functions)), this is specified with an ellipses following the last argument:
```julia-repl
julia> macro assert(ex, msgs...)
           msg_body = isempty(msgs) ? ex : msgs[1]
           msg = string(msg_body)
           return :($ex ? nothing : throw(AssertionError($msg)))
       end
@assert (macro with 1 method)
```
Now `@assert` has two modes of operation, depending upon the number of arguments it receives! If there's only one argument, the tuple of expressions captured by `msgs` will be empty and it will behave the same as the simpler definition above. But now if the user specifies a second argument, it is printed in the message body instead of the failing expression. You can inspect the result of a macro expansion with the aptly named [`@macroexpand`](../../base/base/#Base.@macroexpand) macro:
```julia-repl
julia> @macroexpand @assert a == b
:(if Main.a == Main.b
        Main.nothing
    else
        Main.throw(Main.AssertionError("a == b"))
    end)

julia> @macroexpand @assert a==b "a should equal b!"
:(if Main.a == Main.b
        Main.nothing
    else
        Main.throw(Main.AssertionError("a should equal b!"))
    end)
```


### [Building an advanced macro](#Building-an-advanced-macro)
There is yet another case that the actual `@assert` macro handles: what if, in addition to printing "a should equal b," we wanted to print their values? One might naively try to use string interpolation in the custom message, e.g., `@assert a==b "a ($a) should equal b ($b)!"`, but this won't work as expected with the above macro. Can you see why? Recall from [string interpolation](../strings/#string-interpolation) that an interpolated string is rewritten to a call to [`string`](../../base/strings/#Base.string). Compare:
```julia-repl
julia> typeof(:("a should equal b"))
String

julia> typeof(:("a ($a) should equal b ($b)!"))
Expr

julia> dump(:("a ($a) should equal b ($b)!"))
Expr
  head: Symbol string
  args: Array{Any}((5,))
    1: String "a ("
    2: Symbol a
    3: String ") should equal b ("
    4: Symbol b
    5: String ")!"
```
So now instead of getting a plain string in `msg_body`, the macro is receiving a full expression that will need to be evaluated in order to display as expected. This can be spliced directly into the returned expression as an argument to the [`string`](../../base/strings/#Base.string) call; see [`error.jl`](https://github.com/JuliaLang/julia/blob/master/base/error.jl) for the complete implementation.
The `@assert` macro makes great use of splicing into quoted expressions to simplify the manipulation of expressions inside the macro body.


### [Hygiene](#Hygiene)
An issue that arises in more complex macros is that of [hygiene](https://en.wikipedia.org/wiki/Hygienic_macro). In short, macros must ensure that the variables they introduce in their returned expressions do not accidentally clash with existing variables in the surrounding code they expand into. Conversely, the expressions that are passed into a macro as arguments are often *expected* to evaluate in the context of the surrounding code, interacting with and modifying the existing variables. Another concern arises from the fact that a macro may be called in a different module from where it was defined. In this case we need to ensure that all global variables are resolved to the correct module. Julia already has a major advantage over languages with textual macro expansion (like C) in that it only needs to consider the returned expression. All the other variables (such as `msg` in `@assert` above) follow the [normal scoping block behavior](../variables-and-scoping/#scope-of-variables).
To demonstrate these issues, let us consider writing a `@time` macro that takes an expression as its argument, records the time, evaluates the expression, records the time again, prints the difference between the before and after times, and then has the value of the expression as its final value. The macro might look like this:
```julia
macro time(ex)
    return quote
        local t0 = time_ns()
        local val = $ex
        local t1 = time_ns()
        println("elapsed time: ", (t1-t0)/1e9, " seconds")
        val
    end
end
```


### [Hygiene](#Hygiene)
Here, we want `t0`, `t1`, and `val` to be private temporary variables, and we want `time_ns` to refer to the [`time_ns`](../../base/base/#Base.time_ns) function in Julia Base, not to any `time_ns` variable the user might have (the same applies to `println`). Imagine the problems that could occur if the user expression `ex` also contained assignments to a variable called `t0`, or defined its own `time_ns` variable. We might get errors, or mysteriously incorrect behavior.
Julia's macro expander solves these problems in the following way. First, variables within a macro result are classified as either local or global. A variable is considered local if it is assigned to (and not declared global), declared local, or used as a function argument name. Otherwise, it is considered global. Local variables are then renamed to be unique (using the [`gensym`](../../base/base/#Base.gensym) function, which generates new symbols), and global variables are resolved within the macro definition environment. Therefore both of the above concerns are handled; the macro's locals will not conflict with any user variables, and `time_ns` and `println` will refer to the Julia Base definitions.
One problem remains however. Consider the following use of this macro:
```julia
module MyModule
import Base.@time

time_ns() = ... # compute something

@time time_ns()
end
```


### [Hygiene](#Hygiene)
Here the user expression `ex` is a call to `time_ns`, but not the same `time_ns` function that the macro uses. It clearly refers to `MyModule.time_ns`. Therefore we must arrange for the code in `ex` to be resolved in the macro call environment. This is done by "escaping" the expression with [`esc`](../../base/base/#Base.esc):
```julia
macro time(ex)
    ...
    local val = $(esc(ex))
    ...
end
```
An expression wrapped in this manner is left alone by the macro expander and simply pasted into the output verbatim. Therefore it will be resolved in the macro call environment.
This escaping mechanism can be used to "violate" hygiene when necessary, in order to introduce or manipulate user variables. For example, the following macro sets `x` to zero in the call environment:
```julia-repl
julia> macro zerox()
           return esc(:(x = 0))
       end
@zerox (macro with 1 method)

julia> function foo()
           x = 1
           @zerox
           return x # is zero
       end
foo (generic function with 1 method)

julia> foo()
0
```
This kind of manipulation of variables should be used judiciously, but is occasionally quite handy.


### [Hygiene](#Hygiene)
Getting the hygiene rules correct can be a formidable challenge. Before using a macro, you might want to consider whether a function closure would be sufficient. Another useful strategy is to defer as much work as possible to runtime. For example, many macros simply wrap their arguments in a `QuoteNode` or other similar [`Expr`](../../base/base/#Core.Expr). Some examples of this include `@task body` which simply returns `schedule(Task(() -> $body))`, and `@eval expr`, which simply returns `eval(QuoteNode(expr))`.
To demonstrate, we might rewrite the `@time` example above as:
```julia
macro time(expr)
    return :(timeit(() -> $(esc(expr))))
end
function timeit(f)
    t0 = time_ns()
    val = f()
    t1 = time_ns()
    println("elapsed time: ", (t1-t0)/1e9, " seconds")
    return val
end
```
However, we don't do this for a good reason: wrapping the `expr` in a new scope block (the anonymous function) also slightly changes the meaning of the expression (the scope of any variables in it), while we want `@time` to be usable with minimum impact on the wrapped code.


### [Macros and dispatch](#Macros-and-dispatch)
Macros, just like Julia functions, are generic. This means they can also have multiple method definitions, thanks to multiple dispatch:
```julia-repl
julia> macro m end
@m (macro with 0 methods)

julia> macro m(args...)
           println("$(length(args)) arguments")
       end
@m (macro with 1 method)

julia> macro m(x,y)
           println("Two arguments")
       end
@m (macro with 2 methods)

julia> @m "asd"
1 arguments

julia> @m 1 2
Two arguments
```
However one should keep in mind, that macro dispatch is based on the types of AST that are handed to the macro, not the types that the AST evaluates to at runtime:
```julia-repl
julia> macro m(::Int)
           println("An Integer")
       end
@m (macro with 3 methods)

julia> @m 2
An Integer

julia> x = 2
2

julia> @m x
1 arguments
```


## [Code Generation](#Code-Generation)
When a significant amount of repetitive boilerplate code is required, it is common to generate it programmatically to avoid redundancy. In most languages, this requires an extra build step, and a separate program to generate the repetitive code. In Julia, expression interpolation and [`eval`](../../base/base/#eval) allow such code generation to take place in the normal course of program execution. For example, consider the following custom type
```julia
struct MyNumber
    x::Float64
end
# output
```
for which we want to add a number of methods to. We can do this programmatically in the following loop:
```julia
for op = (:sin, :cos, :tan, :log, :exp)
    eval(quote
        Base.$op(a::MyNumber) = MyNumber($op(a.x))
    end)
end
# output
```
and we can now use those functions with our custom type:
```julia-repl
julia> x = MyNumber(π)
MyNumber(3.141592653589793)

julia> sin(x)
MyNumber(1.2246467991473532e-16)

julia> cos(x)
MyNumber(-1.0)
```
In this manner, Julia acts as its own [preprocessor](https://en.wikipedia.org/wiki/Preprocessor), and allows code generation from inside the language. The above code could be written slightly more tersely using the `:` prefix quoting form:
```julia
for op = (:sin, :cos, :tan, :log, :exp)
    eval(:(Base.$op(a::MyNumber) = MyNumber($op(a.x))))
end
```
This sort of in-language code generation, however, using the `eval(quote(...))` pattern, is common enough that Julia comes with a macro to abbreviate this pattern:


## [Code Generation](#Code-Generation)
```julia
for op = (:sin, :cos, :tan, :log, :exp)
    @eval Base.$op(a::MyNumber) = MyNumber($op(a.x))
end
```
The [`@eval`](../../base/base/#Base.@eval) macro rewrites this call to be precisely equivalent to the above longer versions. For longer blocks of generated code, the expression argument given to [`@eval`](../../base/base/#Base.@eval) can be a block:
```julia
@eval begin
    # multiple lines
end
```


## [Non-Standard String Literals](#meta-non-standard-string-literals)
Recall from [Strings](../strings/#non-standard-string-literals) that string literals prefixed by an identifier are called non-standard string literals, and can have different semantics than un-prefixed string literals. For example:
-   `r"^\s*(?:#|$)"` produces a [regular expression object](../strings/#man-regex-literals) rather than a string
-   `b"DATA\xff\u2200"` is a [byte array literal](../strings/#man-byte-array-literals) for `[68,65,84,65,255,226,136,128]`.
Perhaps surprisingly, these behaviors are not hard-coded into the Julia parser or compiler. Instead, they are custom behaviors provided by a general mechanism that anyone can use: prefixed string literals are parsed as calls to specially-named macros. For example, the regular expression macro is just the following:
```julia
macro r_str(p)
    Regex(p)
end
```
That's all. This macro says that the literal contents of the string literal `r"^\s*(?:#|$)"` should be passed to the `@r_str` macro and the result of that expansion should be placed in the syntax tree where the string literal occurs. In other words, the expression `r"^\s*(?:#|$)"` is equivalent to placing the following object directly into the syntax tree:
```julia
Regex("^\\s*(?:#|\$)")
```


## [Non-Standard String Literals](#meta-non-standard-string-literals)
Not only is the string literal form shorter and far more convenient, but it is also more efficient: since the regular expression is compiled and the `Regex` object is actually created *when the code is compiled*, the compilation occurs only once, rather than every time the code is executed. Consider if the regular expression occurs in a loop:
```julia
for line = lines
    m = match(r"^\s*(?:#|$)", line)
    if m === nothing
        # non-comment
    else
        # comment
    end
end
```
Since the regular expression `r"^\s*(?:#|$)"` is compiled and inserted into the syntax tree when this code is parsed, the expression is only compiled once instead of each time the loop is executed. In order to accomplish this without macros, one would have to write this loop like this:
```julia
re = Regex("^\\s*(?:#|\$)")
for line = lines
    m = match(re, line)
    if m === nothing
        # non-comment
    else
        # comment
    end
end
```


## [Non-Standard String Literals](#meta-non-standard-string-literals)
Moreover, if the compiler could not determine that the regex object was constant over all loops, certain optimizations might not be possible, making this version still less efficient than the more convenient literal form above. Of course, there are still situations where the non-literal form is more convenient: if one needs to interpolate a variable into the regular expression, one must take this more verbose approach; in cases where the regular expression pattern itself is dynamic, potentially changing upon each loop iteration, a new regular expression object must be constructed on each iteration. In the vast majority of use cases, however, regular expressions are not constructed based on run-time data. In this majority of cases, the ability to write regular expressions as compile-time values is invaluable.
The mechanism for user-defined string literals is deeply, profoundly powerful. Not only are Julia's non-standard literals implemented using it, but the command literal syntax (`` `echo "Hello, $person"` ``) is also implemented using the following innocuous-looking macro:
```julia
macro cmd(str)
    :(cmd_gen($(shell_parse(str)[1])))
end
```
Of course, a large amount of complexity is hidden in the functions used in this macro definition, but they are just functions, written entirely in Julia. You can read their source and see precisely what they do – and all they do is construct expression objects to be inserted into your program's syntax tree.


## [Non-Standard String Literals](#meta-non-standard-string-literals)
Like string literals, command literals can also be prefixed by an identifier to form what are called non-standard command literals. These command literals are parsed as calls to specially-named macros. For example, the syntax `` custom`literal` `` is parsed as `@custom_cmd "literal"`. Julia itself does not contain any non-standard command literals, but packages can make use of this syntax. Aside from the different syntax and the `_cmd` suffix instead of the `_str` suffix, non-standard command literals behave exactly like non-standard string literals.
In the event that two modules provide non-standard string or command literals with the same name, it is possible to qualify the string or command literal with a module name. For instance, if both `Foo` and `Bar` provide non-standard string literal `@x_str`, then one can write `Foo.x"literal"` or `Bar.x"literal"` to disambiguate between the two.
Another way to define a macro would be like this:
```julia
macro foo_str(str, flag)
    # do stuff
end
```
This macro can then be called with the following syntax:
```julia
foo"str"flag
```
The type of flag in the above mentioned syntax would be a `String` with contents of whatever trails after the string literal.


## [Generated functions](#Generated-functions)
A very special macro is [`@generated`](../../base/base/#Base.@generated), which allows you to define so-called *generated functions*. These have the capability to generate specialized code depending on the types of their arguments with more flexibility and/or less code than what can be achieved with multiple dispatch. While macros work with expressions at parse time and cannot access the types of their inputs, a generated function gets expanded at a time when the types of the arguments are known, but the function is not yet compiled.
Instead of performing some calculation or action, a generated function declaration returns a quoted expression which then forms the body for the method corresponding to the types of the arguments. When a generated function is called, the expression it returns is compiled and then run. To make this efficient, the result is usually cached. And to make this inferable, only a limited subset of the language is usable. Thus, generated functions provide a flexible way to move work from run time to compile time, at the expense of greater restrictions on allowed constructs.
When defining generated functions, there are five main differences to ordinary functions:
1.  You annotate the function declaration with the `@generated` macro. This adds some information to the AST that lets the compiler know that this is a generated function.
2.  In the body of the generated function you only have access to the *types* of the arguments – not their values.


## [Generated functions](#Generated-functions)
3.  Instead of calculating something or performing some action, you return a *quoted expression* which, when evaluated, does what you want.
4.  Generated functions are only permitted to call functions that were defined *before* the definition of the generated function. (Failure to follow this may result in getting `MethodErrors` referring to functions from a future world-age.)
5.  Generated functions must not *mutate* or *observe* any non-constant global state (including, for example, IO, locks, non-local dictionaries, or using [`hasmethod`](../../base/base/#Base.hasmethod)). This means they can only read global constants, and cannot have any side effects. In other words, they must be completely pure. Due to an implementation limitation, this also means that they currently cannot define a closure or generator.
It's easiest to illustrate this with an example. We can declare a generated function `foo` as
```julia-repl
julia> @generated function foo(x)
           Core.println(x)
           return :(x * x)
       end
foo (generic function with 1 method)
```
Note that the body returns a quoted expression, namely `:(x * x)`, rather than just the value of `x * x`.
From the caller's perspective, this is identical to a regular function; in fact, you don't have to know whether you're calling a regular or generated function. Let's see how `foo` behaves:
```julia-repl
julia> x = foo(2); # note: output is from println() statement in the body
Int64

julia> x           # now we print x
4

julia> y = foo("bar");
String

julia> y
"barbar"
```


## [Generated functions](#Generated-functions)
So, we see that in the body of the generated function, `x` is the *type* of the passed argument, and the value returned by the generated function, is the result of evaluating the quoted expression we returned from the definition, now with the *value* of `x`.
What happens if we evaluate `foo` again with a type that we have already used?
```julia-repl
julia> foo(4)
16
```
Note that there is no printout of [`Int64`](../../base/numbers/#Core.Int64). We can see that the body of the generated function was only executed once here, for the specific set of argument types, and the result was cached. After that, for this example, the expression returned from the generated function on the first invocation was re-used as the method body. However, the actual caching behavior is an implementation-defined performance optimization, so it is invalid to depend too closely on this behavior.
The number of times a generated function is generated *might* be only once, but it *might* also be more often, or appear to not happen at all. As a consequence, you should *never* write a generated function with side effects - when, and how often, the side effects occur is undefined. (This is true for macros too - and just like for macros, the use of [`eval`](../../base/base/#eval) in a generated function is a sign that you're doing something the wrong way.) However, unlike macros, the runtime system cannot correctly handle a call to [`eval`](../../base/base/#eval), so it is disallowed.


## [Generated functions](#Generated-functions)
It is also important to see how `@generated` functions interact with method redefinition. Following the principle that a correct `@generated` function must not observe any mutable state or cause any mutation of global state, we see the following behavior. Observe that the generated function *cannot* call any method that was not defined prior to the *definition* of the generated function itself.
Initially `f(x)` has one definition
```julia-repl
julia> f(x) = "original definition";
```
Define other operations that use `f(x)`:
```julia-repl
julia> g(x) = f(x);

julia> @generated gen1(x) = f(x);

julia> @generated gen2(x) = :(f(x));
```
We now add some new definitions for `f(x)`:
```julia-repl
julia> f(x::Int) = "definition for Int";

julia> f(x::Type{Int}) = "definition for Type{Int}";
```
and compare how these results differ:
```julia-repl
julia> f(1)
"definition for Int"

julia> g(1)
"definition for Int"

julia> gen1(1)
"original definition"

julia> gen2(1)
"definition for Int"
```
Each method of a generated function has its own view of defined functions:
```julia-repl
julia> @generated gen1(x::Real) = f(x);

julia> gen1(1)
"definition for Type{Int}"
```
The example generated function `foo` above did not do anything a normal function `foo(x) = x * x` could not do (except printing the type on the first invocation, and incurring higher overhead). However, the power of a generated function lies in its ability to compute different quoted expressions depending on the types passed to it:


## [Generated functions](#Generated-functions)
```julia-repl
julia> @generated function bar(x)
           if x <: Integer
               return :(x ^ 2)
           else
               return :(x)
           end
       end
bar (generic function with 1 method)

julia> bar(4)
16

julia> bar("baz")
"baz"
```
(although of course this contrived example would be more easily implemented using multiple dispatch...)
Abusing this will corrupt the runtime system and cause undefined behavior:
```julia-repl
julia> @generated function baz(x)
           if rand() < .9
               return :(x^2)
           else
               return :("boo!")
           end
       end
baz (generic function with 1 method)
```
Since the body of the generated function is non-deterministic, its behavior, *and the behavior of all subsequent code* is undefined.
*Don't copy these examples!*
These examples are hopefully helpful to illustrate how generated functions work, both in the definition end and at the call site; however, *don't copy them*, for the following reasons:
-   the `foo` function has side-effects (the call to `Core.println`), and it is undefined exactly when, how often or how many times these side-effects will occur
-   the `bar` function solves a problem that is better solved with multiple dispatch - defining `bar(x) = x` and `bar(x::Integer) = x ^ 2` will do the same thing, but it is both simpler and faster.
-   the `baz` function is pathological


## [Generated functions](#Generated-functions)
Note that the set of operations that should not be attempted in a generated function is unbounded, and the runtime system can currently only detect a subset of the invalid operations. There are many other operations that will simply corrupt the runtime system without notification, usually in subtle ways not obviously connected to the bad definition. Because the function generator is run during inference, it must respect all of the limitations of that code.
Some operations that should not be attempted include:
1.  Caching of native pointers.
2.  Interacting with the contents or methods of `Core.Compiler` in any way.
3.  Observing any mutable state.
    -   Inference on the generated function may be run at *any* time, including while your code is attempting to observe or mutate this state.
4.  Taking any locks: C code you call out to may use locks internally, (for example, it is not problematic to call `malloc`, even though most implementations require locks internally) but don't attempt to hold or acquire any while executing Julia code.
5.  Calling any function that is defined after the body of the generated function. This condition is relaxed for incrementally-loaded precompiled modules to allow calling any function in the module.
Alright, now that we have a better understanding of how generated functions work, let's use them to build some more advanced (and valid) functionality...


### [An advanced example](#An-advanced-example)
Julia's base library has an internal `sub2ind` function to calculate a linear index into an n-dimensional array, based on a set of n multilinear indices - in other words, to calculate the index `i` that can be used to index into an array `A` using `A[i]`, instead of `A[x,y,z,...]`. One possible implementation is the following:
```julia-repl
julia> function sub2ind_loop(dims::NTuple{N}, I::Integer...) where N
           ind = I[N] - 1
           for i = N-1:-1:1
               ind = I[i]-1 + dims[i]*ind
           end
           return ind + 1
       end;

julia> sub2ind_loop((3, 5), 1, 2)
4
```
The same thing can be done using recursion:
```julia-repl
julia> sub2ind_rec(dims::Tuple{}) = 1;

julia> sub2ind_rec(dims::Tuple{}, i1::Integer, I::Integer...) =
           i1 == 1 ? sub2ind_rec(dims, I...) : throw(BoundsError());

julia> sub2ind_rec(dims::Tuple{Integer, Vararg{Integer}}, i1::Integer) = i1;

julia> sub2ind_rec(dims::Tuple{Integer, Vararg{Integer}}, i1::Integer, I::Integer...) =
           i1 + dims[1] * (sub2ind_rec(Base.tail(dims), I...) - 1);

julia> sub2ind_rec((3, 5), 1, 2)
4
```
Both these implementations, although different, do essentially the same thing: a runtime loop over the dimensions of the array, collecting the offset in each dimension into the final index.


### [An advanced example](#An-advanced-example)
However, all the information we need for the loop is embedded in the type information of the arguments. This allows the compiler to move the iteration to compile time and eliminate the runtime loops altogether. We can utilize generated functions to achieve a similar effect; in compiler parlance, we use generated functions to manually unroll the loop. The body becomes almost identical, but instead of calculating the linear index, we build up an *expression* that calculates the index:
```julia-repl
julia> @generated function sub2ind_gen(dims::NTuple{N}, I::Integer...) where N
           ex = :(I[$N] - 1)
           for i = (N - 1):-1:1
               ex = :(I[$i] - 1 + dims[$i] * $ex)
           end
           return :($ex + 1)
       end;

julia> sub2ind_gen((3, 5), 1, 2)
4
```
**What code will this generate?**
An easy way to find out is to extract the body into another (regular) function:
```julia-repl
julia> function sub2ind_gen_impl(dims::Type{T}, I...) where T <: NTuple{N,Any} where N
           length(I) == N || return :(error("partial indexing is unsupported"))
           ex = :(I[$N] - 1)
           for i = (N - 1):-1:1
               ex = :(I[$i] - 1 + dims[$i] * $ex)
           end
           return :($ex + 1)
       end;

julia> @generated function sub2ind_gen(dims::NTuple{N}, I::Integer...) where N
           return sub2ind_gen_impl(dims, I...)
       end;

julia> sub2ind_gen((3, 5), 1, 2)
4
```
We can now execute `sub2ind_gen_impl` and examine the expression it returns:


### [An advanced example](#An-advanced-example)
```julia-repl
julia> sub2ind_gen_impl(Tuple{Int,Int}, Int, Int)
:(((I[1] - 1) + dims[1] * (I[2] - 1)) + 1)
```
So, the method body that will be used here doesn't include a loop at all - just indexing into the two tuples, multiplication and addition/subtraction. All the looping is performed compile-time, and we avoid looping during execution entirely. Thus, we only loop *once per type*, in this case once per `N` (except in edge cases where the function is generated more than once - see disclaimer above).


### [Optionally-generated functions](#Optionally-generated-functions)
Generated functions can achieve high efficiency at run time, but come with a compile time cost: a new function body must be generated for every combination of concrete argument types. Typically, Julia is able to compile "generic" versions of functions that will work for any arguments, but with generated functions this is impossible. This means that programs making heavy use of generated functions might be impossible to statically compile.
To solve this problem, the language provides syntax for writing normal, non-generated alternative implementations of generated functions. Applied to the `sub2ind` example above, it would look like this:
```julia-repl
julia> function sub2ind_gen_impl(dims::Type{T}, I...) where T <: NTuple{N,Any} where N
           ex = :(I[$N] - 1)
           for i = (N - 1):-1:1
               ex = :(I[$i] - 1 + dims[$i] * $ex)
           end
           return :($ex + 1)
       end;

julia> function sub2ind_gen_fallback(dims::NTuple{N}, I) where N
           ind = I[N] - 1
           for i = (N - 1):-1:1
               ind = I[i] - 1 + dims[i]*ind
           end
           return ind + 1
       end;

julia> function sub2ind_gen(dims::NTuple{N}, I::Integer...) where N
           length(I) == N || error("partial indexing is unsupported")
           if @generated
               return sub2ind_gen_impl(dims, I...)
           else
               return sub2ind_gen_fallback(dims, I)
           end
       end;

julia> sub2ind_gen((3, 5), 1, 2)
4
```


### [Optionally-generated functions](#Optionally-generated-functions)
Internally, this code creates two implementations of the function: a generated one where the first block in `if @generated` is used, and a normal one where the `else` block is used. Inside the `then` part of the `if @generated` block, code has the same semantics as other generated functions: argument names refer to types, and the code should return an expression. Multiple `if @generated` blocks may occur, in which case the generated implementation uses all of the `then` blocks and the alternate implementation uses all of the `else` blocks.
Notice that we added an error check to the top of the function. This code will be common to both versions, and is run-time code in both versions (it will be quoted and returned as an expression from the generated version). That means that the values and types of local variables are not available at code generation time –- the code-generation code can only see the types of arguments.
In this style of definition, the code generation feature is essentially an optional optimization. The compiler will use it if convenient, but otherwise may choose to use the normal implementation instead. This style is preferred, since it allows the compiler to make more decisions and compile programs in more ways, and since normal code is more readable than code-generating code. However, which implementation is used depends on compiler implementation details, so it is essential for the two implementations to behave identically.


### [Optionally-generated functions](#Optionally-generated-functions)
------------------------------------------------------------------------


# Single- and multi-dimensional Arrays · The Julia Language
Source: https://docs.julialang.org/en/v1/manual/arrays/


# [Single- and multi-dimensional Arrays](#man-multi-dim-arrays)
Julia, like most technical computing languages, provides a first-class array implementation. Most technical computing languages pay a lot of attention to their array implementation at the expense of other containers. Julia does not treat arrays in any special way. The array library is implemented almost completely in Julia itself, and derives its performance from the compiler, just like any other code written in Julia. As such, it's also possible to define custom array types by inheriting from [`AbstractArray`](../../base/arrays/#Core.AbstractArray). See the [manual section on the AbstractArray interface](../interfaces/#man-interface-array) for more details on implementing a custom array type.
An array is a collection of objects stored in a multi-dimensional grid. Zero-dimensional arrays are allowed, see [this FAQ entry](../faq/#faq-array-0dim). In the most general case, an array may contain objects of type [`Any`](../../base/base/#Core.Any). For most computational purposes, arrays should contain objects of a more specific type, such as [`Float64`](../../base/numbers/#Core.Float64) or [`Int32`](../../base/numbers/#Core.Int32).
In general, unlike many other technical computing languages, Julia does not expect programs to be written in a vectorized style for performance. Julia's compiler uses type inference and generates optimized code for scalar array indexing, allowing programs to be written in a style that is convenient and readable, without sacrificing performance, and using less memory at times.


# [Single- and multi-dimensional Arrays](#man-multi-dim-arrays)
In Julia, all arguments to functions are [passed by sharing](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing) (i.e. by pointers). Some technical computing languages pass arrays by value, and while this prevents accidental modification by callees of a value in the caller, it makes avoiding unwanted copying of arrays difficult. By convention, a function name ending with a `!` indicates that it will mutate or destroy the value of one or more of its arguments (compare, for example, [`sort`](../../base/sort/#Base.sort) and [`sort!`](../../base/sort/#Base.sort!)). Callees must make explicit copies to ensure that they don't modify inputs that they don't intend to change. Many non-mutating functions are implemented by calling a function of the same name with an added `!` at the end on an explicit copy of the input, and returning that copy.


## [Basic Functions](#Basic-Functions)
| Function                                                               | Description                                                                      |
|:-----------------------------------------------------------------------|:---------------------------------------------------------------------------------|
| [`eltype(A)`](../../base/collections/#Base.eltype)                     | the type of the elements contained in `A`                                        |
| [`length(A)`](../../base/arrays/#Base.length-Tuple%7BAbstractArray%7D) | the number of elements in `A`                                                    |
| [`ndims(A)`](../../base/arrays/#Base.ndims)                            | the number of dimensions of `A`                                                  |
| [`size(A)`](../../base/arrays/#Base.size)                              | a tuple containing the dimensions of `A`                                         |
| [`size(A,n)`](../../base/arrays/#Base.size)                            | the size of `A` along dimension `n`                                              |
| [`axes(A)`](../../base/arrays/#Base.axes-Tuple%7BAny%7D)               | a tuple containing the valid indices of `A`                                      |
| [`axes(A,n)`](../../base/arrays/#Base.axes-Tuple%7BAny%7D)             | a range expressing the valid indices along dimension `n`                         |
| [`eachindex(A)`](../../base/arrays/#Base.eachindex)                    | an efficient iterator for visiting each position in `A`                          |
| [`stride(A,k)`](../../base/arrays/#Base.stride)                        | the stride (linear index distance between adjacent elements) along dimension `k` |
| [`strides(A)`](../../base/arrays/#Base.strides)                        | a tuple of the strides in each dimension                                         |


## [Construction and Initialization](#Construction-and-Initialization)
Many functions for constructing and initializing arrays are provided. In the following list of such functions, calls with a `dims...` argument can either take a single tuple of dimension sizes or a series of dimension sizes passed as a variable number of arguments. Most of these functions also accept a first input `T`, which is the element type of the array. If the type `T` is omitted it will default to [`Float64`](../../base/numbers/#Core.Float64).
| Function                                                    | Description                                                                                |
|:------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [`Array{T}(undef, dims...)`](../../base/arrays/#Core.Array) | an uninitialized dense [`Array`](../../base/arrays/#Core.Array)                                                                                |
| [`zeros(T, dims...)`](../../base/arrays/#Base.zeros)        | an `Array` of all zeros                                                                                |
| [`ones(T, dims...)`](../../base/arrays/#Base.ones)          | an `Array` of all ones                                                                                |
| [`trues(dims...)`](../../base/arrays/#Base.trues)           | a [`BitArray`](../../base/arrays/#Base.BitArray) with all values `true`                                                                                |
| [`falses(dims...)`](../../base/arrays/#Base.falses)         | a `BitArray` with all values `false`                                                                                |
| [`reshape(A, dims...)`](../../base/arrays/#Base.reshape)    | an array containing the same data as `A`, but with different dimensions                                                                                |
| [`copy(A)`](../../base/base/#Base.copy)                     | copy `A`                                                                                |
| [`deepcopy(A)`](../../base/base/#Base.deepcopy)             | copy `A`, recursively copying its elements                                                                                |
| [`similar(A, T, dims...)`](../../base/arrays/#Base.similar) | an uninitialized array of the same type as `A` (dense, sparse, etc.), but with the specified element type and dimensions. The second and third arguments are both optional, defaulting to the element type and dimensions of `A` if omitted. |
| [`reinterpret(T, A)`](../../base/arrays/#Base.reinterpret)  | an array with the same binary data as `A`, but with element type `T`                                                                                |
| [`rand(T, dims...)`](../../stdlib/Random/#Base.rand)        | an `Array` with random, iid <sup>[[1\]](#footnote-1)</sup> and uniformly distributed values. For floating point types `T`, the values lie in the half-open interval $\[0, 1)$.                                      |
| [`randn(T, dims...)`](../../stdlib/Random/#Base.randn)      | an `Array` with random, iid and standard normally distributed values                                                                                |
| [`Matrix{T}(I, m, n)`](../../base/arrays/#Base.Matrix)      | `m`-by-`n` identity matrix. Requires `using LinearAlgebra` for [`I`](../../stdlib/LinearAlgebra/#LinearAlgebra.I).                                                                                |
| [`range(start, stop, n)`](../../base/math/#Base.range)      | a range of `n` linearly spaced elements from `start` to `stop`                                                                                |
| [`fill!(A, x)`](../../base/arrays/#Base.fill!)              | fill the array `A` with the value `x`                                                                                |
| [`fill(x, dims...)`](../../base/arrays/#Base.fill)          | an `Array` filled with the value `x`. In particular, `fill(x)` constructs a zero-dimensional `Array` containing `x`.                                                                                |


## [Construction and Initialization](#Construction-and-Initialization)
To see the various ways we can pass dimensions to these functions, consider the following examples:
```julia-repl
julia> zeros(Int8, 2, 3)
2×3 Matrix{Int8}:
 0  0  0
 0  0  0

julia> zeros(Int8, (2, 3))
2×3 Matrix{Int8}:
 0  0  0
 0  0  0

julia> zeros((2, 3))
2×3 Matrix{Float64}:
 0.0  0.0  0.0
 0.0  0.0  0.0
```
Here, `(2, 3)` is a [`Tuple`](../../base/base/#Core.Tuple) and the first argument — the element type — is optional, defaulting to `Float64`.


## [Array literals](#man-array-literals)
Arrays can also be directly constructed with square braces; the syntax `[A, B, C, ...]` creates a one-dimensional array (i.e., a vector) containing the comma-separated arguments as its elements. The element type ([`eltype`](../../base/collections/#Base.eltype)) of the resulting array is automatically determined by the types of the arguments inside the braces. If all the arguments are the same type, then that is its `eltype`. If they all have a common [promotion type](../conversion-and-promotion/#conversion-and-promotion) then they get converted to that type using [`convert`](../../base/base/#Base.convert) and that type is the array's `eltype`. Otherwise, a heterogeneous array that can hold anything — a `Vector{Any}` — is constructed; this includes the literal `[]` where no arguments are given. [Array literal can be typed](#man-array-typed-literal) with the syntax `T[A, B, C, ...]` where `T` is a type.
```julia-repl
julia> [1, 2, 3] # An array of `Int`s
3-element Vector{Int64}:
 1
 2
 3

julia> promote(1, 2.3, 4//5) # This combination of Int, Float64 and Rational promotes to Float64
(1.0, 2.3, 0.8)

julia> [1, 2.3, 4//5] # Thus that's the element type of this Array
3-element Vector{Float64}:
 1.0
 2.3
 0.8

julia> Float32[1, 2.3, 4//5] # Specify element type manually
3-element Vector{Float32}:
 1.0
 2.3
 0.8

julia> []
Any[]
```


### [Concatenation](#man-array-concatenation)
If the arguments inside the square brackets are separated by single semicolons (`;`) or newlines instead of commas, then their contents are *vertically concatenated* together instead of the arguments being used as elements themselves.
```julia-repl
julia> [1:2, 4:5] # Has a comma, so no concatenation occurs. The ranges are themselves the elements
2-element Vector{UnitRange{Int64}}:
 1:2
 4:5

julia> [1:2; 4:5]
4-element Vector{Int64}:
 1
 2
 4
 5

julia> [1:2
        4:5
        6]
5-element Vector{Int64}:
 1
 2
 4
 5
 6
```
Similarly, if the arguments are separated by tabs or spaces or double semicolons, then their contents are *horizontally concatenated* together.
```julia-repl
julia> [1:2  4:5  7:8]
2×3 Matrix{Int64}:
 1  4  7
 2  5  8

julia> [[1,2]  [4,5]  [7,8]]
2×3 Matrix{Int64}:
 1  4  7
 2  5  8

julia> [1 2 3] # Numbers can also be horizontally concatenated
1×3 Matrix{Int64}:
 1  2  3

julia> [1;; 2;; 3;; 4]
1×4 Matrix{Int64}:
 1  2  3  4
```
Single semicolons (or newlines) and spaces (or tabs) can be combined to concatenate both horizontally and vertically at the same time.
```julia-repl
julia> [1 2
        3 4]
2×2 Matrix{Int64}:
 1  2
 3  4

julia> [zeros(Int, 2, 2) [1; 2]
        [3 4]            5]
3×3 Matrix{Int64}:
 0  0  1
 0  0  2
 3  4  5

julia> [[1 1]; 2 3; [4 4]]
3×2 Matrix{Int64}:
 1  1
 2  3
 4  4
```


### [Concatenation](#man-array-concatenation)
Spaces (and tabs) have a higher precedence than semicolons, performing any horizontal concatenations first and then concatenating the result. Using double semicolons for the horizontal concatenation, on the other hand, performs any vertical concatenations before horizontally concatenating the result.
```julia-repl
julia> [zeros(Int, 2, 2) ; [3 4] ;; [1; 2] ; 5]
3×3 Matrix{Int64}:
 0  0  1
 0  0  2
 3  4  5

julia> [1:2; 4;; 1; 3:4]
3×2 Matrix{Int64}:
 1  1
 2  3
 4  4
```
Just as `;` and `;;` concatenate in the first and second dimension, using more semicolons extends this same general scheme. The number of semicolons in the separator specifies the particular dimension, so `;;;` concatenates in the third dimension, `;;;;` in the 4th, and so on. Fewer semicolons take precedence, so the lower dimensions are generally concatenated first.
```julia-repl
julia> [1; 2;; 3; 4;; 5; 6;;;
        7; 8;; 9; 10;; 11; 12]
2×3×2 Array{Int64, 3}:
[:, :, 1] =
 1  3  5
 2  4  6

[:, :, 2] =
 7   9  11
 8  10  12
```
Like before, spaces (and tabs) for horizontal concatenation have a higher precedence than any number of semicolons. Thus, higher-dimensional arrays can also be written by specifying their rows first, with their elements textually arranged in a manner similar to their layout:


### [Concatenation](#man-array-concatenation)
```julia-repl
julia> [1 3 5
        2 4 6;;;
        7 9 11
        8 10 12]
2×3×2 Array{Int64, 3}:
[:, :, 1] =
 1  3  5
 2  4  6

[:, :, 2] =
 7   9  11
 8  10  12

julia> [1 2;;; 3 4;;;; 5 6;;; 7 8]
1×2×2×2 Array{Int64, 4}:
[:, :, 1, 1] =
 1  2

[:, :, 2, 1] =
 3  4

[:, :, 1, 2] =
 5  6

[:, :, 2, 2] =
 7  8

julia> [[1 2;;; 3 4];;;; [5 6];;; [7 8]]
1×2×2×2 Array{Int64, 4}:
[:, :, 1, 1] =
 1  2

[:, :, 2, 1] =
 3  4

[:, :, 1, 2] =
 5  6

[:, :, 2, 2] =
 7  8
```
Although they both mean concatenation in the second dimension, spaces (or tabs) and `;;` cannot appear in the same array expression unless the double semicolon is simply serving as a "line continuation" character. This allows a single horizontal concatenation to span multiple lines (without the line break being interpreted as a vertical concatenation).
```julia-repl
julia> [1 2 ;;
       3 4]
1×4 Matrix{Int64}:
 1  2  3  4
```
Terminating semicolons may also be used to add trailing length 1 dimensions.
```julia-repl
julia> [1;;]
1×1 Matrix{Int64}:
 1

julia> [2; 3;;;]
2×1×1 Array{Int64, 3}:
[:, :, 1] =
 2
 3
```
More generally, concatenation can be accomplished through the [`cat`](../../base/arrays/#Base.cat) function. These syntaxes are shorthands for function calls that themselves are convenience functions:


### [Concatenation](#man-array-concatenation)
| Syntax                 | Function                                   | Description                                                                                |
|:-----------------------|:-------------------------------------------|:-----------------------------------------------------------------------------------------------------------|
|                        | [`cat`](../../base/arrays/#Base.cat)       | concatenate input arrays along dimension(s) `k`                                                            |
| `[A; B; C; ...]`       | [`vcat`](../../base/arrays/#Base.vcat)     | shorthand for `cat(A...; dims=1)`                                                                          |
| `[A B C ...]`          | [`hcat`](../../base/arrays/#Base.hcat)     | shorthand for `cat(A...; dims=2)`                                                                          |
| `[A B; C D; ...]`      | [`hvcat`](../../base/arrays/#Base.hvcat)   | simultaneous vertical and horizontal concatenation                                                         |
| `[A; C;; B; D;;; ...]` | [`hvncat`](../../base/arrays/#Base.hvncat) | simultaneous n-dimensional concatenation, where number of semicolons indicate the dimension to concatenate |


### [Typed array literals](#man-array-typed-literal)
An array with a specific element type can be constructed using the syntax `T[A, B, C, ...]`. This will construct a 1-d array with element type `T`, initialized to contain elements `A`, `B`, `C`, etc. For example, `Any[x, y, z]` constructs a heterogeneous array that can contain any values.
Concatenation syntax can similarly be prefixed with a type to specify the element type of the result.
```julia-repl
julia> [[1 2] [3 4]]
1×4 Matrix{Int64}:
 1  2  3  4

julia> Int8[[1 2] [3 4]]
1×4 Matrix{Int8}:
 1  2  3  4
```


## [Comprehensions](#man-comprehensions)
Comprehensions provide a general and powerful way to construct arrays. Comprehension syntax is similar to set construction notation in mathematics:
```julia
A = [ F(x, y, ...) for x=rx, y=ry, ... ]
```
The meaning of this form is that `F(x,y,...)` is evaluated with the variables `x`, `y`, etc. taking on each value in their given list of values. Values can be specified as any iterable object, but will commonly be ranges like `1:n` or `2:(n-1)`, or explicit arrays of values like `[1.2, 3.4, 5.7]`. The result is an N-d dense array with dimensions that are the concatenation of the dimensions of the variable ranges `rx`, `ry`, etc. and each `F(x,y,...)` evaluation returns a scalar.
The following example computes a weighted average of the current element and its left and right neighbor along a 1-d grid. :
```julia-repl
julia> x = rand(8)
8-element Array{Float64,1}:
 0.843025
 0.869052
 0.365105
 0.699456
 0.977653
 0.994953
 0.41084
 0.809411

julia> [ 0.25*x[i-1] + 0.5*x[i] + 0.25*x[i+1] for i=2:length(x)-1 ]
6-element Array{Float64,1}:
 0.736559
 0.57468
 0.685417
 0.912429
 0.8446
 0.656511
```
The resulting array type depends on the types of the computed elements just like [array literals](#man-array-literals) do. In order to control the type explicitly, a type can be prepended to the comprehension. For example, we could have requested the result in single precision by writing:
```julia
Float32[ 0.25*x[i-1] + 0.5*x[i] + 0.25*x[i+1] for i=2:length(x)-1 ]
```


## [Generator Expressions](#man-generators)
Comprehensions can also be written without the enclosing square brackets, producing an object known as a generator. This object can be iterated to produce values on demand, instead of allocating an array and storing them in advance (see [Iteration](#Iteration)). For example, the following expression sums a series without allocating memory:
```julia-repl
julia> sum(1/n^2 for n=1:1000)
1.6439345666815615
```
When writing a generator expression with multiple dimensions inside an argument list, parentheses are needed to separate the generator from subsequent arguments:
```julia-repl
julia> map(tuple, 1/(i+j) for i=1:2, j=1:2, [1:4;])
ERROR: syntax: invalid iteration specification
```
All comma-separated expressions after `for` are interpreted as ranges. Adding parentheses lets us add a third argument to [`map`](../../base/collections/#Base.map):
```julia-repl
julia> map(tuple, (1/(i+j) for i=1:2, j=1:2), [1 3; 2 4])
2×2 Matrix{Tuple{Float64, Int64}}:
 (0.5, 1)       (0.333333, 3)
 (0.333333, 2)  (0.25, 4)
```
Generators are implemented via inner functions. Just like inner functions used elsewhere in the language, variables from the enclosing scope can be "captured" in the inner function. For example, `sum(p[i] - q[i] for i=1:n)` captures the three variables `p`, `q` and `n` from the enclosing scope. Captured variables can present performance challenges; see [performance tips](../performance-tips/#man-performance-captured).
Ranges in generators and comprehensions can depend on previous ranges by writing multiple `for` keywords:


## [Generator Expressions](#man-generators)
```julia-repl
julia> [(i, j) for i=1:3 for j=1:i]
6-element Vector{Tuple{Int64, Int64}}:
 (1, 1)
 (2, 1)
 (2, 2)
 (3, 1)
 (3, 2)
 (3, 3)
```
In such cases, the result is always 1-d.
Generated values can be filtered using the `if` keyword:
```julia-repl
julia> [(i, j) for i=1:3 for j=1:i if i+j == 4]
2-element Vector{Tuple{Int64, Int64}}:
 (2, 2)
 (3, 1)
```


## [Indexing](#man-array-indexing)
The general syntax for indexing into an n-dimensional array `A` is:
```julia
X = A[I_1, I_2, ..., I_n]
```
where each `I_k` may be a scalar integer, an array of integers, or any other [supported index](#man-supported-index-types). This includes [`Colon`](../../base/arrays/#Base.Colon) (`:`) to select all indices within the entire dimension, ranges of the form `a:c` or `a:b:c` to select contiguous or strided subsections, and arrays of booleans to select elements at their `true` indices.
If all the indices are scalars, then the result `X` is a single element from the array `A`. Otherwise, `X` is an array with the same number of dimensions as the sum of the dimensionalities of all the indices.
If all indices `I_k` are vectors, for example, then the shape of `X` would be `(length(I_1), length(I_2), ..., length(I_n))`, with location `i_1, i_2, ..., i_n` of `X` containing the value `A[I_1[i_1], I_2[i_2], ..., I_n[i_n]]`.
Example:
```julia-repl
julia> A = reshape(collect(1:16), (2, 2, 2, 2))
2×2×2×2 Array{Int64, 4}:
[:, :, 1, 1] =
 1  3
 2  4

[:, :, 2, 1] =
 5  7
 6  8

[:, :, 1, 2] =
  9  11
 10  12

[:, :, 2, 2] =
 13  15
 14  16

julia> A[1, 2, 1, 1] # all scalar indices
3

julia> A[[1, 2], [1], [1, 2], [1]] # all vector indices
2×1×2×1 Array{Int64, 4}:
[:, :, 1, 1] =
 1
 2

[:, :, 2, 1] =
 5
 6

julia> A[[1, 2], [1], [1, 2], 1] # a mix of index types
2×1×2 Array{Int64, 3}:
[:, :, 1] =
 1
 2

[:, :, 2] =
 5
 6
```
Note how the size of the resulting array is different in the last two cases.


## [Indexing](#man-array-indexing)
If `I_1` is changed to a two-dimensional matrix, then `X` becomes an `n+1`-dimensional array of shape `(size(I_1, 1), size(I_1, 2), length(I_2), ..., length(I_n))`. The matrix adds a dimension.
Example:
```julia-repl
julia> A = reshape(collect(1:16), (2, 2, 2, 2));

julia> A[[1 2; 1 2]]
2×2 Matrix{Int64}:
 1  2
 1  2

julia> A[[1 2; 1 2], 1, 2, 1]
2×2 Matrix{Int64}:
 5  6
 5  6
```
The location `i_1, i_2, i_3, ..., i_{n+1}` contains the value at `A[I_1[i_1, i_2], I_2[i_3], ..., I_n[i_{n+1}]]`. All dimensions indexed with scalars are dropped. For example, if `J` is an array of indices, then the result of `A[2, J, 3]` is an array with size `size(J)`. Its `j`th element is populated by `A[2, J[j], 3]`.
As a special part of this syntax, the `end` keyword may be used to represent the last index of each dimension within the indexing brackets, as determined by the size of the innermost array being indexed. Indexing syntax without the `end` keyword is equivalent to a call to [`getindex`](../../base/collections/#Base.getindex):
```julia
X = getindex(A, I_1, I_2, ..., I_n)
```
Example:
```julia-repl
julia> x = reshape(1:16, 4, 4)
4×4 reshape(::UnitRange{Int64}, 4, 4) with eltype Int64:
 1  5   9  13
 2  6  10  14
 3  7  11  15
 4  8  12  16

julia> x[2:3, 2:end-1]
2×2 Matrix{Int64}:
 6  10
 7  11

julia> x[1, [2 3; 4 1]]
2×2 Matrix{Int64}:
  5  9
 13  1
```


## [Indexed Assignment](#man-indexed-assignment)
The general syntax for assigning values in an n-dimensional array `A` is:
```julia
A[I_1, I_2, ..., I_n] = X
```
where each `I_k` may be a scalar integer, an array of integers, or any other [supported index](#man-supported-index-types). This includes [`Colon`](../../base/arrays/#Base.Colon) (`:`) to select all indices within the entire dimension, ranges of the form `a:c` or `a:b:c` to select contiguous or strided subsections, and arrays of booleans to select elements at their `true` indices.
If all indices `I_k` are integers, then the value in location `I_1, I_2, ..., I_n` of `A` is overwritten with the value of `X`, [`convert`](../../base/base/#Base.convert)ing to the [`eltype`](../../base/collections/#Base.eltype) of `A` if necessary.
If any index `I_k` is itself an array, then the right hand side `X` must also be an array with the same shape as the result of indexing `A[I_1, I_2, ..., I_n]` or a vector with the same number of elements. The value in location `I_1[i_1], I_2[i_2], ..., I_n[i_n]` of `A` is overwritten with the value `X[i_1, i_2, ..., i_n]`, converting if necessary. The element-wise assignment operator `.=` may be used to [broadcast](#Broadcasting) `X` across the selected locations:
```julia
A[I_1, I_2, ..., I_n] .= X
```


## [Indexed Assignment](#man-indexed-assignment)
Just as in [Indexing](#man-array-indexing), the `end` keyword may be used to represent the last index of each dimension within the indexing brackets, as determined by the size of the array being assigned into. Indexed assignment syntax without the `end` keyword is equivalent to a call to [`setindex!`](../../base/collections/#Base.setindex!):
```julia
setindex!(A, X, I_1, I_2, ..., I_n)
```
Example:
```julia-repl
julia> x = collect(reshape(1:9, 3, 3))
3×3 Matrix{Int64}:
 1  4  7
 2  5  8
 3  6  9

julia> x[3, 3] = -9;

julia> x[1:2, 1:2] = [-1 -4; -2 -5];

julia> x
3×3 Matrix{Int64}:
 -1  -4   7
 -2  -5   8
  3   6  -9
```


## [Supported index types](#man-supported-index-types)
In the expression `A[I_1, I_2, ..., I_n]`, each `I_k` may be a scalar index, an array of scalar indices, or an object that represents an array of scalar indices and can be converted to such by [`to_indices`](../../base/arrays/#Base.to_indices):
1.  A scalar index. By default this includes:
    -   Non-boolean integers
    -   [`CartesianIndex{N}`](../../base/arrays/#Base.IteratorsMD.CartesianIndex)s, which behave like an `N`-tuple of integers spanning multiple dimensions (see below for more details)
2.  An array of scalar indices. This includes:
    -   Vectors and multidimensional arrays of integers
    -   Empty arrays like `[]`, which select no elements e.g. `A[[]]` (not to be confused with `A[]`)
    -   Ranges like `a:c` or `a:b:c`, which select contiguous or strided subsections from `a` to `c` (inclusive)
    -   Any custom array of scalar indices that is a subtype of `AbstractArray`
    -   Arrays of `CartesianIndex{N}` (see below for more details)
3.  An object that represents an array of scalar indices and can be converted to such by [`to_indices`](../../base/arrays/#Base.to_indices). By default this includes:
    -   [`Colon()`](../../base/arrays/#Base.Colon) (`:`), which represents all indices within an entire dimension or across the entire array
    -   Arrays of booleans, which select elements at their `true` indices (see below for more details)
Some examples:


## [Supported index types](#man-supported-index-types)
```julia-repl
julia> A = reshape(collect(1:2:18), (3, 3))
3×3 Matrix{Int64}:
 1   7  13
 3   9  15
 5  11  17

julia> A[4]
7

julia> A[[2, 5, 8]]
3-element Vector{Int64}:
  3
  9
 15

julia> A[[1 4; 3 8]]
2×2 Matrix{Int64}:
 1   7
 5  15

julia> A[[]]
Int64[]

julia> A[1:2:5]
3-element Vector{Int64}:
 1
 5
 9

julia> A[2, :]
3-element Vector{Int64}:
  3
  9
 15

julia> A[:, 3]
3-element Vector{Int64}:
 13
 15
 17

julia> A[:, 3:3]
3×1 Matrix{Int64}:
 13
 15
 17
```


### [Cartesian indices](#Cartesian-indices)
The special `CartesianIndex{N}` object represents a scalar index that behaves like an `N`-tuple of integers spanning multiple dimensions. For example:
```julia-repl
julia> A = reshape(1:32, 4, 4, 2);

julia> A[3, 2, 1]
7

julia> A[CartesianIndex(3, 2, 1)] == A[3, 2, 1] == 7
true
```
Considered alone, this may seem relatively trivial; `CartesianIndex` simply gathers multiple integers together into one object that represents a single multidimensional index. When combined with other indexing forms and iterators that yield `CartesianIndex`es, however, this can produce very elegant and efficient code. See [Iteration](#Iteration) below, and for some more advanced examples, see [this blog post on multidimensional algorithms and iteration](https://julialang.org/blog/2016/02/iteration).
Arrays of `CartesianIndex{N}` are also supported. They represent a collection of scalar indices that each span `N` dimensions, enabling a form of indexing that is sometimes referred to as pointwise indexing. For example, it enables accessing the diagonal elements from the first "page" of `A` from above:
```julia-repl
julia> page = A[:, :, 1]
4×4 Matrix{Int64}:
 1  5   9  13
 2  6  10  14
 3  7  11  15
 4  8  12  16

julia> page[[CartesianIndex(1, 1),
             CartesianIndex(2, 2),
             CartesianIndex(3, 3),
             CartesianIndex(4, 4)]]
4-element Vector{Int64}:
  1
  6
 11
 16
```


### [Cartesian indices](#Cartesian-indices)
This can be expressed much more simply with [dot broadcasting](../functions/#man-vectorized) and by combining it with a normal integer index (instead of extracting the first `page` from `A` as a separate step). It can even be combined with a `:` to extract both diagonals from the two pages at the same time:
```julia-repl
julia> A[CartesianIndex.(axes(A, 1), axes(A, 2)), 1]
4-element Vector{Int64}:
  1
  6
 11
 16

julia> A[CartesianIndex.(axes(A, 1), axes(A, 2)), :]
4×2 Matrix{Int64}:
  1  17
  6  22
 11  27
 16  32
```
`CartesianIndex` and arrays of `CartesianIndex` are not compatible with the `end` keyword to represent the last index of a dimension. Do not use `end` in indexing expressions that may contain either `CartesianIndex` or arrays thereof.


### [Logical indexing](#Logical-indexing)
Often referred to as logical indexing or indexing with a logical mask, indexing by a boolean array selects elements at the indices where its values are `true`. Indexing by a boolean vector `B` is effectively the same as indexing by the vector of integers that is returned by [`findall(B)`](../../base/arrays/#Base.findall-Tuple%7BAny%7D). Similarly, indexing by a `N`-dimensional boolean array is effectively the same as indexing by the vector of `CartesianIndex{N}`s where its values are `true`. A logical index must be a array of the same shape as the dimension(s) it indexes into, or it must be the only index provided and match the shape of the one-dimensional reshaped view of the array it indexes into. It is generally more efficient to use boolean arrays as indices directly instead of first calling [`findall`](../../base/arrays/#Base.findall-Tuple%7BAny%7D).
```julia-repl
julia> x = reshape(1:12, 2, 3, 2)
2×3×2 reshape(::UnitRange{Int64}, 2, 3, 2) with eltype Int64:
[:, :, 1] =
 1  3  5
 2  4  6

[:, :, 2] =
 7   9  11
 8  10  12

julia> x[:, [true false; false true; true false]]
2×3 Matrix{Int64}:
 1  5   9
 2  6  10

julia> mask = map(ispow2, x)
2×3×2 Array{Bool, 3}:
[:, :, 1] =
 1  0  0
 1  1  0

[:, :, 2] =
 0  0  0
 1  0  0

julia> x[mask]
4-element Vector{Int64}:
 1
 2
 4
 8

julia> x[vec(mask)] == x[mask] # we can also index with a single Boolean vector
true
```


### [Number of indices](#Number-of-indices)


#### [Cartesian indexing](#Cartesian-indexing)
The ordinary way to index into an `N`-dimensional array is to use exactly `N` indices; each index selects the position(s) in its particular dimension. For example, in the three-dimensional array `A = rand(4, 3, 2)`, `A[2, 3, 1]` will select the number in the second row of the third column in the first "page" of the array. This is often referred to as *cartesian indexing*.


#### [Linear indexing](#Linear-indexing)
When exactly one index `i` is provided, that index no longer represents a location in a particular dimension of the array. Instead, it selects the `i`th element using the column-major iteration order that linearly spans the entire array. This is known as *linear indexing*. It essentially treats the array as though it had been reshaped into a one-dimensional vector with [`vec`](../../base/arrays/#Base.vec).
```julia-repl
julia> A = [2 6; 4 7; 3 1]
3×2 Matrix{Int64}:
 2  6
 4  7
 3  1

julia> A[5]
7

julia> vec(A)[5]
7
```
A linear index into the array `A` can be converted to a `CartesianIndex` for cartesian indexing with `CartesianIndices(A)[i]` (see [`CartesianIndices`](../../base/arrays/#Base.IteratorsMD.CartesianIndices)), and a set of `N` cartesian indices can be converted to a linear index with `LinearIndices(A)[i_1, i_2, ..., i_N]` (see [`LinearIndices`](../../base/arrays/#Base.LinearIndices)).
```julia-repl
julia> CartesianIndices(A)[5]
CartesianIndex(2, 2)

julia> LinearIndices(A)[2, 2]
5
```


### [Number of indices](#Number-of-indices)
It's important to note that there's a very large asymmetry in the performance of these conversions. Converting a linear index to a set of cartesian indices requires dividing and taking the remainder, whereas going the other way is just multiplies and adds. In modern processors, integer division can be 10-50 times slower than multiplication. While some arrays — like [`Array`](../../base/arrays/#Core.Array) itself — are implemented using a linear chunk of memory and directly use a linear index in their implementations, other arrays — like [`Diagonal`](../../stdlib/LinearAlgebra/#LinearAlgebra.Diagonal) — need the full set of cartesian indices to do their lookup (see [`IndexStyle`](../../base/arrays/#Base.IndexStyle) to introspect which is which).
When iterating over all the indices for an array, it is better to iterate over [`eachindex(A)`](../../base/arrays/#Base.eachindex) instead of `1:length(A)`. Not only will this be faster in cases where `A` is `IndexCartesian`, but it will also support arrays with custom indexing, such as [OffsetArrays](https://github.com/JuliaArrays/OffsetArrays.jl). If only the values are needed, then is better to just iterate the array directly, i.e. `for a in A`.


#### [Omitted and extra indices](#Omitted-and-extra-indices)
In addition to linear indexing, an `N`-dimensional array may be indexed with fewer or more than `N` indices in certain situations.
Indices may be omitted if the trailing dimensions that are not indexed into are all length one. In other words, trailing indices can be omitted only if there is only one possible value that those omitted indices could be for an in-bounds indexing expression. For example, a four-dimensional array with size `(3, 4, 2, 1)` may be indexed with only three indices as the dimension that gets skipped (the fourth dimension) has length one. Note that linear indexing takes precedence over this rule.
```julia-repl
julia> A = reshape(1:24, 3, 4, 2, 1)
3×4×2×1 reshape(::UnitRange{Int64}, 3, 4, 2, 1) with eltype Int64:
[:, :, 1, 1] =
 1  4  7  10
 2  5  8  11
 3  6  9  12

[:, :, 2, 1] =
 13  16  19  22
 14  17  20  23
 15  18  21  24

julia> A[1, 3, 2] # Omits the fourth dimension (length 1)
19

julia> A[1, 3] # Attempts to omit dimensions 3 & 4 (lengths 2 and 1)
ERROR: BoundsError: attempt to access 3×4×2×1 reshape(::UnitRange{Int64}, 3, 4, 2, 1) with eltype Int64 at index [1, 3]

julia> A[19] # Linear indexing
19
```
When omitting *all* indices with `A[]`, this semantic provides a simple idiom to retrieve the only element in an array and simultaneously ensure that there was only one element.


### [Number of indices](#Number-of-indices)
Similarly, more than `N` indices may be provided if all the indices beyond the dimensionality of the array are `1` (or more generally are the first and only element of `axes(A, d)` where `d` is that particular dimension number). This allows vectors to be indexed like one-column matrices, for example:
```julia-repl
julia> A = [8, 6, 7]
3-element Vector{Int64}:
 8
 6
 7

julia> A[2, 1]
6
```


## [Iteration](#Iteration)
The recommended ways to iterate over a whole array are
```julia
for a in A
    # Do something with the element a
end

for i in eachindex(A)
    # Do something with i and/or A[i]
end
```
The first construct is used when you need the value, but not index, of each element. In the second construct, `i` will be an `Int` if `A` is an array type with fast linear indexing; otherwise, it will be a `CartesianIndex`:
```julia-repl
julia> A = rand(4, 3);

julia> B = view(A, 1:3, 2:3);

julia> for i in eachindex(B)
           @show i
       end
i = CartesianIndex(1, 1)
i = CartesianIndex(2, 1)
i = CartesianIndex(3, 1)
i = CartesianIndex(1, 2)
i = CartesianIndex(2, 2)
i = CartesianIndex(3, 2)
```
In contrast with `for i = 1:length(A)`, iterating with [`eachindex`](../../base/arrays/#Base.eachindex) provides an efficient way to iterate over any array type. Besides, this also supports generic arrays with custom indexing such as [OffsetArrays](https://github.com/JuliaArrays/OffsetArrays.jl).


## [Array traits](#Array-traits)
If you write a custom [`AbstractArray`](../../base/arrays/#Core.AbstractArray) type, you can specify that it has fast linear indexing using
```julia
Base.IndexStyle(::Type{<:MyArray}) = IndexLinear()
```
This setting will cause `eachindex` iteration over a `MyArray` to use integers. If you don't specify this trait, the default value `IndexCartesian()` is used.