## [Unicode and UTF-8](#Unicode-and-UTF-8)
Extraction of a substring using range indexing also expects valid byte indices or an error is thrown:
```julia-repl
julia> s[1:1]
"∀"

julia> s[1:2]
ERROR: StringIndexError: invalid index [2], valid nearby indices [1]=>'∀', [4]=>' '
Stacktrace:
[...]

julia> s[1:4]
"∀ "
```
Because of variable-length encodings, the number of characters in a string (given by [`length(s)`](../../base/arrays/#Base.length-Tuple%7BAbstractArray%7D)) is not always the same as the last index. If you iterate through the indices 1 through [`lastindex(s)`](../../base/collections/#Base.lastindex) and index into `s`, the sequence of characters returned when errors aren't thrown is the sequence of characters comprising the string `s`. Thus `length(s) <= lastindex(s)`, since each character in a string must have its own index. The following is an inefficient and verbose way to iterate through the characters of `s`:
```julia-repl
julia> for i = firstindex(s):lastindex(s)
           try
               println(s[i])
           catch
               # ignore the index error
           end
       end
∀

x

∃

y
```
The blank lines actually have spaces on them. Fortunately, the above awkward idiom is unnecessary for iterating through the characters in a string, since you can just use the string as an iterable object, no exception handling required:
```julia-repl
julia> for c in s
           println(c)
       end
∀

x

∃

y
```


## [Unicode and UTF-8](#Unicode-and-UTF-8)
If you need to obtain valid indices for a string, you can use the [`nextind`](../../base/arrays/#Base.nextind) and [`prevind`](../../base/arrays/#Base.prevind) functions to increment/decrement to the next/previous valid index, as mentioned above. You can also use the [`eachindex`](../../base/arrays/#Base.eachindex) function to iterate over the valid character indices:
```julia-repl
julia> collect(eachindex(s))
7-element Vector{Int64}:
  1
  4
  5
  6
  7
 10
 11
```
To access the raw code units (bytes for UTF-8) of the encoding, you can use the [`codeunit(s,i)`](../../base/strings/#Base.codeunit) function, where the index `i` runs consecutively from `1` to [`ncodeunits(s)`](../../base/strings/#Base.ncodeunits-Tuple%7BAbstractString%7D). The [`codeunits(s)`](../../base/strings/#Base.codeunits) function returns an `AbstractVector{UInt8}` wrapper that lets you access these raw codeunits (bytes) as an array.
Strings in Julia can contain invalid UTF-8 code unit sequences. This convention allows to treat any byte sequence as a `String`. In such situations a rule is that when parsing a sequence of code units from left to right characters are formed by the longest sequence of 8-bit code units that matches the start of one of the following bit patterns (each `x` can be `0` or `1`):
-   `0xxxxxxx`;
-   `110xxxxx` `10xxxxxx`;
-   `1110xxxx` `10xxxxxx` `10xxxxxx`;
-   `11110xxx` `10xxxxxx` `10xxxxxx` `10xxxxxx`;
-   `10xxxxxx`;
-   `11111xxx`.


## [Unicode and UTF-8](#Unicode-and-UTF-8)
In particular this means that overlong and too-high code unit sequences and prefixes thereof are treated as a single invalid character rather than multiple invalid characters. This rule may be best explained with an example:
```julia-repl
julia> s = "\xc0\xa0\xe2\x88\xe2|"
"\xc0\xa0\xe2\x88\xe2|"

julia> foreach(display, s)
'\xc0\xa0': [overlong] ASCII/Unicode U+0020 (category Zs: Separator, space)
'\xe2\x88': Malformed UTF-8 (category Ma: Malformed, bad data)
'\xe2': Malformed UTF-8 (category Ma: Malformed, bad data)
'|': ASCII/Unicode U+007C (category Sm: Symbol, math)

julia> isvalid.(collect(s))
4-element BitArray{1}:
 0
 0
 0
 1

julia> s2 = "\xf7\xbf\xbf\xbf"
"\U1fffff"

julia> foreach(display, s2)
'\U1fffff': Unicode U+1FFFFF (category In: Invalid, too high)
```
We can see that the first two code units in the string `s` form an overlong encoding of space character. It is invalid, but is accepted in a string as a single character. The next two code units form a valid start of a three-byte UTF-8 sequence. However, the fifth code unit `\xe2` is not its valid continuation. Therefore code units 3 and 4 are also interpreted as malformed characters in this string. Similarly code unit 5 forms a malformed character because `|` is not a valid continuation to it. Finally the string `s2` contains one too high code point.


## [Unicode and UTF-8](#Unicode-and-UTF-8)
Julia uses the UTF-8 encoding by default, and support for new encodings can be added by packages. For example, the [LegacyStrings.jl](https://github.com/JuliaStrings/LegacyStrings.jl) package implements `UTF16String` and `UTF32String` types. Additional discussion of other encodings and how to implement support for them is beyond the scope of this document for the time being. For further discussion of UTF-8 encoding issues, see the section below on [byte array literals](#man-byte-array-literals). The [`transcode`](../../base/strings/#Base.transcode) function is provided to convert data between the various UTF-xx encodings, primarily for working with external data and libraries.


## [Concatenation](#man-concatenation)
One of the most common and useful string operations is concatenation:
```julia-repl
julia> greet = "Hello"
"Hello"

julia> whom = "world"
"world"

julia> string(greet, ", ", whom, ".\n")
"Hello, world.\n"
```
It's important to be aware of potentially dangerous situations such as concatenation of invalid UTF-8 strings. The resulting string may contain different characters than the input strings, and its number of characters may be lower than sum of numbers of characters of the concatenated strings, e.g.:
```julia-repl
julia> a, b = "\xe2\x88", "\x80"
("\xe2\x88", "\x80")

julia> c = string(a, b)
"∀"

julia> collect.([a, b, c])
3-element Vector{Vector{Char}}:
 ['\xe2\x88']
 ['\x80']
 ['∀']

julia> length.([a, b, c])
3-element Vector{Int64}:
 1
 1
 1
```
This situation can happen only for invalid UTF-8 strings. For valid UTF-8 strings concatenation preserves all characters in strings and additivity of string lengths.
Julia also provides [`*`](../../base/math/#Base.:*-Tuple%7BAny,%20Vararg%7BAny%7D%7D) for string concatenation:
```julia-repl
julia> greet * ", " * whom * ".\n"
"Hello, world.\n"
```
While `*` may seem like a surprising choice to users of languages that provide `+` for string concatenation, this use of `*` has precedent in mathematics, particularly in abstract algebra.


## [Concatenation](#man-concatenation)
In mathematics, `+` usually denotes a *commutative* operation, where the order of the operands does not matter. An example of this is matrix addition, where `A + B == B + A` for any matrices `A` and `B` that have the same shape. In contrast, `*` typically denotes a *noncommutative* operation, where the order of the operands *does* matter. An example of this is matrix multiplication, where in general `A * B != B * A`. As with matrix multiplication, string concatenation is noncommutative: `greet * whom != whom * greet`. As such, `*` is a more natural choice for an infix string concatenation operator, consistent with common mathematical use.
More precisely, the set of all finite-length strings *S* together with the string concatenation operator `*` forms a [free monoid](https://en.wikipedia.org/wiki/Free_monoid) (*S*, `*`). The identity element of this set is the empty string, `""`. Whenever a free monoid is not commutative, the operation is typically represented as `\cdot`, `*`, or a similar symbol, rather than `+`, which as stated usually implies commutativity.


## [Interpolation](#string-interpolation)
Constructing strings using concatenation can become a bit cumbersome, however. To reduce the need for these verbose calls to [`string`](../../base/strings/#Base.string) or repeated multiplications, Julia allows interpolation into string literals using `$`, as in Perl:
```julia-repl
julia> greet = "Hello"; whom = "world";

julia> "$greet, $whom.\n"
"Hello, world.\n"
```
This is more readable and convenient and equivalent to the above string concatenation – the system rewrites this apparent single string literal into the call `string(greet, ", ", whom, ".\n")`.
The shortest complete expression after the `$` is taken as the expression whose value is to be interpolated into the string. Thus, you can interpolate any expression into a string using parentheses:
```julia-repl
julia> "1 + 2 = $(1 + 2)"
"1 + 2 = 3"
```
Both concatenation and string interpolation call [`string`](../../base/strings/#Base.string) to convert objects into string form. However, `string` actually just returns the output of [`print`](../../base/io-network/#Base.print), so new types should add methods to [`print`](../../base/io-network/#Base.print) or [`show`](../../base/io-network/#Base.show-Tuple%7BIO,%20Any%7D) instead of `string`.
Most non-`AbstractString` objects are converted to strings closely corresponding to how they are entered as literal expressions:
```julia-repl
julia> v = [1,2,3]
3-element Vector{Int64}:
 1
 2
 3

julia> "v: $v"
"v: [1, 2, 3]"
```


## [Interpolation](#string-interpolation)
[`string`](../../base/strings/#Base.string) is the identity for `AbstractString` and `AbstractChar` values, so these are interpolated into strings as themselves, unquoted and unescaped:
```julia-repl
julia> c = 'x'
'x': ASCII/Unicode U+0078 (category Ll: Letter, lowercase)

julia> "hi, $c"
"hi, x"
```
To include a literal `$` in a string literal, escape it with a backslash:
```julia-repl
julia> print("I have \$100 in my account.\n")
I have $100 in my account.
```


## [Triple-Quoted String Literals](#Triple-Quoted-String-Literals)
When strings are created using triple-quotes (`"""..."""`) they have some special behavior that can be useful for creating longer blocks of text.
First, triple-quoted strings are also dedented to the level of the least-indented line. This is useful for defining strings within code that is indented. For example:
```julia-repl
julia> str = """
           Hello,
           world.
         """
"  Hello,\n  world.\n"
```
In this case the final (empty) line before the closing `"""` sets the indentation level.
The dedentation level is determined as the longest common starting sequence of spaces or tabs in all lines, excluding the line following the opening `"""` and lines containing only spaces or tabs (the line containing the closing `"""` is always included). Then for all lines, excluding the text following the opening `"""`, the common starting sequence is removed (including lines containing only spaces and tabs if they start with this sequence), e.g.:
```julia-repl
julia> """    This
         is
           a test"""
"    This\nis\n  a test"
```
Next, if the opening `"""` is followed by a newline, the newline is stripped from the resulting string.
```julia
"""hello"""
```
is equivalent to
```julia
"""
hello"""
```
but
```julia
"""

hello"""
```
will contain a literal newline at the beginning.
Stripping of the newline is performed after the dedentation. For example:
```julia-repl
julia> """
         Hello,
         world."""
"Hello,\nworld."
```


## [Triple-Quoted String Literals](#Triple-Quoted-String-Literals)
If the newline is removed using a backslash, dedentation will be respected as well:
```julia-repl
julia> """
         Averylong\
         word"""
"Averylongword"
```
Trailing whitespace is left unaltered.
Triple-quoted string literals can contain `"` characters without escaping.
Note that line breaks in literal strings, whether single- or triple-quoted, result in a newline (LF) character `\n` in the string, even if your editor uses a carriage return `\r` (CR) or CRLF combination to end lines. To include a CR in a string, use an explicit escape `\r`; for example, you can enter the literal string `"a CRLF line ending\r\n"`.


## [Common Operations](#Common-Operations)
You can lexicographically compare strings using the standard comparison operators:
```julia-repl
julia> "abracadabra" < "xylophone"
true

julia> "abracadabra" == "xylophone"
false

julia> "Hello, world." != "Goodbye, world."
true

julia> "1 + 2 = 3" == "1 + 2 = $(1 + 2)"
true
```
You can search for the index of a particular character using the [`findfirst`](../../base/arrays/#Base.findfirst-Tuple%7BAny%7D) and [`findlast`](../../base/arrays/#Base.findlast-Tuple%7BAny%7D) functions:
```julia-repl
julia> findfirst('o', "xylophone")
4

julia> findlast('o', "xylophone")
7

julia> findfirst('z', "xylophone")
```
You can start the search for a character at a given offset by using the functions [`findnext`](../../base/arrays/#Base.findnext-Tuple%7BAny,%20Integer%7D) and [`findprev`](../../base/arrays/#Base.findprev-Tuple%7BAny,%20Integer%7D):
```julia-repl
julia> findnext('o', "xylophone", 1)
4

julia> findnext('o', "xylophone", 5)
7

julia> findprev('o', "xylophone", 5)
4

julia> findnext('o', "xylophone", 8)
```
You can use the [`occursin`](../../base/strings/#Base.occursin) function to check if a substring is found within a string:
```julia-repl
julia> occursin("world", "Hello, world.")
true

julia> occursin("o", "Xylophon")
true

julia> occursin("a", "Xylophon")
false

julia> occursin('o', "Xylophon")
true
```
The last example shows that [`occursin`](../../base/strings/#Base.occursin) can also look for a character literal.


## [Common Operations](#Common-Operations)
Two other handy string functions are [`repeat`](../../base/arrays/#Base.repeat) and [`join`](../../base/strings/#Base.join):
```julia-repl
julia> repeat(".:Z:.", 10)
".:Z:..:Z:..:Z:..:Z:..:Z:..:Z:..:Z:..:Z:..:Z:..:Z:."

julia> join(["apples", "bananas", "pineapples"], ", ", " and ")
"apples, bananas and pineapples"
```
Some other useful functions include:
-   [`firstindex(str)`](../../base/collections/#Base.firstindex) gives the minimal (byte) index that can be used to index into `str` (always 1 for strings, not necessarily true for other containers).
-   [`lastindex(str)`](../../base/collections/#Base.lastindex) gives the maximal (byte) index that can be used to index into `str`.
-   [`length(str)`](../../base/arrays/#Base.length-Tuple%7BAbstractArray%7D) the number of characters in `str`.
-   [`length(str, i, j)`](../../base/arrays/#Base.length-Tuple%7BAbstractArray%7D) the number of valid character indices in `str` from `i` to `j`.
-   [`ncodeunits(str)`](../../base/strings/#Base.ncodeunits-Tuple%7BAbstractString%7D) number of [code units](https://en.wikipedia.org/wiki/Character_encoding#Terminology) in a string.
-   [`codeunit(str, i)`](../../base/strings/#Base.codeunit) gives the code unit value in the string `str` at index `i`.
-   [`thisind(str, i)`](../../base/strings/#Base.thisind) given an arbitrary index into a string find the first index of the character into which the index points.
-   [`nextind(str, i, n=1)`](../../base/arrays/#Base.nextind) find the start of the `n`th character starting after index `i`.


## [Common Operations](#Common-Operations)
-   [`prevind(str, i, n=1)`](../../base/arrays/#Base.prevind) find the start of the `n`th character starting before index `i`.


## [Non-Standard String Literals](#non-standard-string-literals)
There are situations when you want to construct a string or use string semantics, but the behavior of the standard string construct is not quite what is needed. For these kinds of situations, Julia provides non-standard string literals. A non-standard string literal looks like a regular double-quoted string literal, but is immediately prefixed by an identifier, and may behave differently from a normal string literal.
[Regular expressions](#man-regex-literals), [byte array literals](#man-byte-array-literals), and [version number literals](#man-version-number-literals), as described below, are some examples of non-standard string literals. Users and packages may also define new non-standard string literals. Further documentation is given in the [Metaprogramming](../metaprogramming/#meta-non-standard-string-literals) section.


## [Regular Expressions](#man-regex-literals)
Sometimes you are not looking for an exact string, but a particular *pattern*. For example, suppose you are trying to extract a single date from a large text file. You don’t know what that date is (that’s why you are searching for it), but you do know it will look something like `YYYY-MM-DD`. Regular expressions allow you to specify these patterns and search for them.
Julia uses version 2 of Perl-compatible regular expressions (regexes), as provided by the [PCRE](https://www.pcre.org/) library (see the [PCRE2 syntax description](https://www.pcre.org/current/doc/html/pcre2syntax.html) for more details). Regular expressions are related to strings in two ways: the obvious connection is that regular expressions are used to find regular patterns in strings; the other connection is that regular expressions are themselves input as strings, which are parsed into a state machine that can be used to efficiently search for patterns in strings. In Julia, regular expressions are input using non-standard string literals prefixed with various identifiers beginning with `r`. The most basic regular expression literal without any options turned on just uses `r"..."`:
```julia-repl
julia> re = r"^\s*(?:#|$)"
r"^\s*(?:#|$)"

julia> typeof(re)
Regex
```
To check if a regex matches a string, use [`occursin`](../../base/strings/#Base.occursin):
```julia-repl
julia> occursin(r"^\s*(?:#|$)", "not a comment")
false

julia> occursin(r"^\s*(?:#|$)", "# a comment")
true
```


## [Regular Expressions](#man-regex-literals)
As one can see here, [`occursin`](../../base/strings/#Base.occursin) simply returns true or false, indicating whether a match for the given regex occurs in the string. Commonly, however, one wants to know not just whether a string matched, but also *how* it matched. To capture this information about a match, use the [`match`](../../base/strings/#Base.match) function instead:
```julia-repl
julia> match(r"^\s*(?:#|$)", "not a comment")

julia> match(r"^\s*(?:#|$)", "# a comment")
RegexMatch("#")
```
If the regular expression does not match the given string, [`match`](../../base/strings/#Base.match) returns [`nothing`](../../base/constants/#Core.nothing) – a special value that does not print anything at the interactive prompt. Other than not printing, it is a completely normal value and you can test for it programmatically:
```julia
m = match(r"^\s*(?:#|$)", line)
if m === nothing
    println("not a comment")
else
    println("blank or comment")
end
```
If a regular expression does match, the value returned by [`match`](../../base/strings/#Base.match) is a [`RegexMatch`](../../base/strings/#Base.RegexMatch) object. These objects record how the expression matches, including the substring that the pattern matches and any captured substrings, if there are any. This example only captures the portion of the substring that matches, but perhaps we want to capture any non-blank text after the comment character. We could do the following:


## [Regular Expressions](#man-regex-literals)
```julia-repl
julia> m = match(r"^\s*(?:#\s*(.*?)\s*$)", "# a comment ")
RegexMatch("# a comment ", 1="a comment")
```
When calling [`match`](../../base/strings/#Base.match), you have the option to specify an index at which to start the search. For example:
```julia-repl
julia> m = match(r"[0-9]","aaaa1aaaa2aaaa3",1)
RegexMatch("1")

julia> m = match(r"[0-9]","aaaa1aaaa2aaaa3",6)
RegexMatch("2")

julia> m = match(r"[0-9]","aaaa1aaaa2aaaa3",11)
RegexMatch("3")
```
You can extract the following info from a `RegexMatch` object:
-   the entire substring matched: `m.match`
-   the captured substrings as an array of strings: `m.captures`
-   the offset at which the whole match begins: `m.offset`
-   the offsets of the captured substrings as a vector: `m.offsets`
For when a capture doesn't match, instead of a substring, `m.captures` contains `nothing` in that position, and `m.offsets` has a zero offset (recall that indices in Julia are 1-based, so a zero offset into a string is invalid). Here is a pair of somewhat contrived examples:


## [Regular Expressions](#man-regex-literals)
```julia-repl
julia> m = match(r"(a|b)(c)?(d)", "acd")
RegexMatch("acd", 1="a", 2="c", 3="d")

julia> m.match
"acd"

julia> m.captures
3-element Vector{Union{Nothing, SubString{String}}}:
 "a"
 "c"
 "d"

julia> m.offset
1

julia> m.offsets
3-element Vector{Int64}:
 1
 2
 3

julia> m = match(r"(a|b)(c)?(d)", "ad")
RegexMatch("ad", 1="a", 2=nothing, 3="d")

julia> m.match
"ad"

julia> m.captures
3-element Vector{Union{Nothing, SubString{String}}}:
 "a"
 nothing
 "d"

julia> m.offset
1

julia> m.offsets
3-element Vector{Int64}:
 1
 0
 2
```
It is convenient to have captures returned as an array so that one can use destructuring syntax to bind them to local variables. As a convenience, the `RegexMatch` object implements iterator methods that pass through to the `captures` field, so you can destructure the match object directly:
```julia-repl
julia> first, second, third = m; first
"a"
```
Captures can also be accessed by indexing the `RegexMatch` object with the number or name of the capture group:
```julia-repl
julia> m=match(r"(?<hour>\d+):(?<minute>\d+)","12:45")
RegexMatch("12:45", hour="12", minute="45")

julia> m[:minute]
"45"

julia> m[2]
"45"
```


## [Regular Expressions](#man-regex-literals)
Captures can be referenced in a substitution string when using [`replace`](../../base/collections/#Base.replace-Tuple%7BAny,%20Vararg%7BPair%7D%7D) by using `\n` to refer to the nth capture group and prefixing the substitution string with `s`. Capture group 0 refers to the entire match object. Named capture groups can be referenced in the substitution with `\g<groupname>`. For example:
```julia-repl
julia> replace("first second", r"(\w+) (?<agroup>\w+)" => s"\g<agroup> \1")
"second first"
```
Numbered capture groups can also be referenced as `\g<n>` for disambiguation, as in:
```julia-repl
julia> replace("a", r"." => s"\g<0>1")
"a1"
```
You can modify the behavior of regular expressions by some combination of the flags `i`, `m`, `s`, and `x` after the closing double quote mark. These flags have the same meaning as they do in Perl, as explained in this excerpt from the [perlre manpage](https://perldoc.perl.org/perlre#Modifiers):


## [Regular Expressions](#man-regex-literals)
```julia
i   Do case-insensitive pattern matching.

    If locale matching rules are in effect, the case map is taken
    from the current locale for code points less than 255, and
    from Unicode rules for larger code points. However, matches
    that would cross the Unicode rules/non-Unicode rules boundary
    (ords 255/256) will not succeed.

m   Treat string as multiple lines.  That is, change "^" and "$"
    from matching the start or end of the string to matching the
    start or end of any line anywhere within the string.

s   Treat string as single line.  That is, change "." to match any
    character whatsoever, even a newline, which normally it would
    not match.

    Used together, as r""ms, they let the "." match any character
    whatsoever, while still allowing "^" and "$" to match,
    respectively, just after and just before newlines within the
    string.

x   Tells the regular expression parser to ignore most whitespace
    that is neither backslashed nor within a character class. You
    can use this to break up your regular expression into
    (slightly) more readable parts. The '#' character is also
    treated as a metacharacter introducing a comment, just as in
    ordinary code.
```
For example, the following regex has all three flags turned on:
```julia-repl
julia> r"a+.*b+.*d$"ism
r"a+.*b+.*d$"ims

julia> match(r"a+.*b+.*d$"ism, "Goodbye,\nOh, angry,\nBad world\n")
RegexMatch("angry,\nBad world")
```


## [Regular Expressions](#man-regex-literals)
The `r"..."` literal is constructed without interpolation and unescaping (except for quotation mark `"` which still has to be escaped). Here is an example showing the difference from standard string literals:
```julia-repl
julia> x = 10
10

julia> r"$x"
r"$x"

julia> "$x"
"10"

julia> r"\x"
r"\x"

julia> "\x"
ERROR: syntax: invalid escape sequence
```
Triple-quoted regex strings, of the form `r"""..."""`, are also supported (and may be convenient for regular expressions containing quotation marks or newlines).
The `Regex()` constructor may be used to create a valid regex string programmatically. This permits using the contents of string variables and other string operations when constructing the regex string. Any of the regex codes above can be used within the single string argument to `Regex()`. Here are some examples:
```julia-repl
julia> using Dates

julia> d = Date(1962,7,10)
1962-07-10

julia> regex_d = Regex("Day " * string(day(d)))
r"Day 10"

julia> match(regex_d, "It happened on Day 10")
RegexMatch("Day 10")

julia> name = "Jon"
"Jon"

julia> regex_name = Regex("[\"( ]\\Q$name\\E[\") ]")  # interpolate value of name
r"[\"( ]\QJon\E[\") ]"

julia> match(regex_name, " Jon ")
RegexMatch(" Jon ")

julia> match(regex_name, "[Jon]") === nothing
true
```


## [Regular Expressions](#man-regex-literals)
Note the use of the `\Q...\E` escape sequence. All characters between the `\Q` and the `\E` are interpreted as literal characters. This is convenient for matching characters that would otherwise be regex metacharacters. However, caution is needed when using this feature together with string interpolation, since the interpolated string might itself contain the `\E` sequence, unexpectedly terminating literal matching. User inputs need to be sanitized before inclusion in a regex.


## [Byte Array Literals](#man-byte-array-literals)
Another useful non-standard string literal is the byte-array string literal: `b"..."`. This form lets you use string notation to express read only literal byte arrays – i.e. arrays of [`UInt8`](../../base/numbers/#Core.UInt8) values. The type of those objects is `CodeUnits{UInt8, String}`. The rules for byte array literals are the following:
-   ASCII characters and ASCII escapes produce a single byte.
-   `\x` and octal escape sequences produce the *byte* corresponding to the escape value.
-   Unicode escape sequences produce a sequence of bytes encoding that code point in UTF-8.
There is some overlap between these rules since the behavior of `\x` and octal escapes less than 0x80 (128) are covered by both of the first two rules, but here these rules agree. Together, these rules allow one to easily use ASCII characters, arbitrary byte values, and UTF-8 sequences to produce arrays of bytes. Here is an example using all three:
```julia-repl
julia> b"DATA\xff\u2200"
8-element Base.CodeUnits{UInt8, String}:
 0x44
 0x41
 0x54
 0x41
 0xff
 0xe2
 0x88
 0x80
```
The ASCII string "DATA" corresponds to the bytes 68, 65, 84, 65. `\xff` produces the single byte 255. The Unicode escape `\u2200` is encoded in UTF-8 as the three bytes 226, 136, 128. Note that the resulting byte array does not correspond to a valid UTF-8 string:
```julia-repl
julia> isvalid("DATA\xff\u2200")
false
```


## [Byte Array Literals](#man-byte-array-literals)
As it was mentioned `CodeUnits{UInt8, String}` type behaves like read only array of `UInt8` and if you need a standard vector you can convert it using `Vector{UInt8}`:
```julia-repl
julia> x = b"123"
3-element Base.CodeUnits{UInt8, String}:
 0x31
 0x32
 0x33

julia> x[1]
0x31

julia> x[1] = 0x32
ERROR: CanonicalIndexError: setindex! not defined for Base.CodeUnits{UInt8, String}
[...]

julia> Vector{UInt8}(x)
3-element Vector{UInt8}:
 0x31
 0x32
 0x33
```
Also observe the significant distinction between `\xff` and `\uff`: the former escape sequence encodes the *byte 255*, whereas the latter escape sequence represents the *code point 255*, which is encoded as two bytes in UTF-8:
```julia-repl
julia> b"\xff"
1-element Base.CodeUnits{UInt8, String}:
 0xff

julia> b"\uff"
2-element Base.CodeUnits{UInt8, String}:
 0xc3
 0xbf
```
Character literals use the same behavior.
For code points less than `\u80`, it happens that the UTF-8 encoding of each code point is just the single byte produced by the corresponding `\x` escape, so the distinction can safely be ignored. For the escapes `\x80` through `\xff` as compared to `\u80` through `\uff`, however, there is a major difference: the former escapes all encode single bytes, which – unless followed by very specific continuation bytes – do not form valid UTF-8 data, whereas the latter escapes all represent Unicode code points with two-byte encodings.


## [Byte Array Literals](#man-byte-array-literals)
If this is all extremely confusing, try reading ["The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets"](https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/). It's an excellent introduction to Unicode and UTF-8, and may help alleviate some confusion regarding the matter.


## [Version Number Literals](#man-version-number-literals)
Version numbers can easily be expressed with non-standard string literals of the form [`v"..."`](../../base/base/#Base.@v_str). Version number literals create [`VersionNumber`](../../base/base/#Base.VersionNumber) objects which follow the specifications of [semantic versioning](https://semver.org/), and therefore are composed of major, minor and patch numeric values, followed by pre-release and build alphanumeric annotations. For example, `v"0.2.1-rc1+win64"` is broken into major version `0`, minor version `2`, patch version `1`, pre-release `rc1` and build `win64`. When entering a version literal, everything except the major version number is optional, therefore e.g. `v"0.2"` is equivalent to `v"0.2.0"` (with empty pre-release/build annotations), `v"2"` is equivalent to `v"2.0.0"`, and so on.
`VersionNumber` objects are mostly useful to easily and correctly compare two (or more) versions. For example, the constant [`VERSION`](../../base/constants/#Base.VERSION) holds Julia version number as a `VersionNumber` object, and therefore one can define some version-specific behavior using simple statements as:
```julia
if v"0.2" <= VERSION < v"0.3-"
    # do something specific to 0.2 release series
end
```


## [Version Number Literals](#man-version-number-literals)
Note that in the above example the non-standard version number `v"0.3-"` is used, with a trailing `-`: this notation is a Julia extension of the standard, and it's used to indicate a version which is lower than any `0.3` release, including all of its pre-releases. So in the above example the code would only run with stable `0.2` versions, and exclude such versions as `v"0.3.0-rc1"`. In order to also allow for unstable (i.e. pre-release) `0.2` versions, the lower bound check should be modified like this: `v"0.2-" <= VERSION`.
Another non-standard version specification extension allows one to use a trailing `+` to express an upper limit on build versions, e.g. `VERSION > v"0.2-rc1+"` can be used to mean any version above `0.2-rc1` and any of its builds: it will return `false` for version `v"0.2-rc1+win64"` and `true` for `v"0.2-rc2"`.
It is good practice to use such special versions in comparisons (particularly, the trailing `-` should always be used on upper bounds unless there's a good reason not to), but they must not be used as the actual version number of anything, as they are invalid in the semantic versioning scheme.
Besides being used for the [`VERSION`](../../base/constants/#Base.VERSION) constant, `VersionNumber` objects are widely used in the `Pkg` module, to specify packages versions and their dependencies.


## [Raw String Literals](#man-raw-string-literals)
Raw strings without interpolation or unescaping can be expressed with non-standard string literals of the form `raw"..."`. Raw string literals create ordinary `String` objects which contain the enclosed contents exactly as entered with no interpolation or unescaping. This is useful for strings which contain code or markup in other languages which use `$` or `\` as special characters.
The exception is that quotation marks still must be escaped, e.g. `raw"\""` is equivalent to `"\""`. To make it possible to express all strings, backslashes then also must be escaped, but only when appearing right before a quote character:
```julia-repl
julia> println(raw"\\ \\\"")
\\ \"
```
Notice that the first two backslashes appear verbatim in the output, since they do not precede a quote character. However, the next backslash character escapes the backslash that follows it, and the last backslash escapes a quote, since these backslashes appear before a quote.


## [Annotated Strings](#man-annotated-strings)
The API for AnnotatedStrings is considered experimental and is subject to change between Julia versions.
It is sometimes useful to be able to hold metadata relating to regions of a string. A [`AnnotatedString`](../../base/strings/#Base.AnnotatedString) wraps another string and allows for regions of it to be annotated with labelled values (`:label => value`). All generic string operations are applied to the underlying string. However, when possible, styling information is preserved. This means you can manipulate a [`AnnotatedString`](../../base/strings/#Base.AnnotatedString) —taking substrings, padding them, concatenating them with other strings— and the metadata annotations will "come along for the ride".
This string type is fundamental to the [StyledStrings stdlib](../../stdlib/StyledStrings/#stdlib-styledstrings), which uses `:face`-labelled annotations to hold styling information.
When concatenating a [`AnnotatedString`](../../base/strings/#Base.AnnotatedString), take care to use [`annotatedstring`](../../base/strings/#Base.annotatedstring) instead of [`string`](../../base/strings/#Base.string) if you want to keep the string annotations.


## [Annotated Strings](#man-annotated-strings)
```julia-repl
julia> str = Base.AnnotatedString("hello there",
               [(1:5, :word, :greeting), (7:11, :label, 1)])
"hello there"

julia> length(str)
11

julia> lpad(str, 14)
"   hello there"

julia> typeof(lpad(str, 7))
Base.AnnotatedString{String}

julia> str2 = Base.AnnotatedString(" julia", [(2:6, :face, :magenta)])
" julia"

julia> Base.annotatedstring(str, str2)
"hello there julia"

julia> str * str2 == Base.annotatedstring(str, str2) # *-concatenation still works
true
```
The annotations of a [`AnnotatedString`](../../base/strings/#Base.AnnotatedString) can be accessed and modified via the [`annotations`](../../base/strings/#Base.annotations) and [`annotate!`](../../base/strings/#Base.annotate!) functions.
------------------------------------------------------------------------


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


# [Functions](#man-functions)
In Julia, a function is an object that maps a tuple of argument values to a return value. Julia functions are not pure mathematical functions, because they can alter and be affected by the global state of the program. The basic syntax for defining functions in Julia is:
```julia-repl
julia> function f(x, y)
           x + y
       end
f (generic function with 1 method)
```
This function accepts two arguments `x` and `y` and returns the value of the last expression evaluated, which is `x + y`.
There is a second, more terse syntax for defining a function in Julia. The traditional function declaration syntax demonstrated above is equivalent to the following compact "assignment form":
```julia-repl
julia> f(x, y) = x + y
f (generic function with 1 method)
```
In the assignment form, the body of the function must be a single expression, although it can be a compound expression (see [Compound Expressions](../control-flow/#man-compound-expressions)). Short, simple function definitions are common in Julia. The short function syntax is accordingly quite idiomatic, considerably reducing both typing and visual noise.
A function is called using the traditional parenthesis syntax:
```julia-repl
julia> f(2, 3)
5
```
Without parentheses, the expression `f` refers to the function object, and can be passed around like any other value:
```julia-repl
julia> g = f;

julia> g(2, 3)
5
```
As with variables, Unicode can also be used for function names:
```julia-repl
julia> ∑(x, y) = x + y
∑ (generic function with 1 method)

julia> ∑(2, 3)
5
```


## [Argument Passing Behavior](#man-argument-passing)
Julia function arguments follow a convention sometimes called "pass-by-sharing", which means that values are not copied when they are passed to functions. Function arguments themselves act as new variable *bindings* (new "names" that can refer to values), much like [assignments](../variables/#man-assignment-expressions) `argument_name = argument_value`, so that the objects they refer to are identical to the passed values. Modifications to mutable values (such as `Array`s) made within a function will be visible to the caller. (This is the same behavior found in Scheme, most Lisps, Python, Ruby and Perl, among other dynamic languages.)
For example, in the function
```julia
function f(x, y)
    x[1] = 42    # mutates x
    y = 7 + y    # new binding for y, no mutation
    return y
end
```
The statement `x[1] = 42` *mutates* the object `x`, and hence this change *will* be visible in the array passed by the caller for this argument. On the other hand, the assignment `y = 7 + y` changes the *binding* ("name") `y` to refer to a new value `7 + y`, rather than mutating the *original* object referred to by `y`, and hence does *not* change the corresponding argument passed by the caller. This can be seen if we call `f(x, y)`:
```julia-repl
julia> a = [4, 5, 6]
3-element Vector{Int64}:
 4
 5
 6

julia> b = 3
3

julia> f(a, b) # returns 7 + b == 10
10

julia> a  # a[1] is changed to 42 by f
3-element Vector{Int64}:
 42
  5
  6

julia> b  # not changed
3
```


## [Argument Passing Behavior](#man-argument-passing)
As a common convention in Julia (not a syntactic requirement), such a function would [typically be named `f!(x, y)`](../../base/punctuation/#man-punctuation) rather than `f(x, y)`, as a visual reminder at the call site that at least one of the arguments (often the first one) is being mutated.
The behavior of a mutating function can be unexpected when a mutated argument shares memory with another argument, a situation known as aliasing (e.g. when one is a view of the other). Unless the function docstring explicitly indicates that aliasing produces the expected result, it is the responsibility of the caller to ensure proper behavior on such inputs.


## [Argument-type declarations](#Argument-type-declarations)
You can declare the types of function arguments by appending `::TypeName` to the argument name, as usual for [Type Declarations](../types/#Type-Declarations) in Julia. For example, the following function computes [Fibonacci numbers](https://en.wikipedia.org/wiki/Fibonacci_number) recursively:
```julia
fib(n::Integer) = n ≤ 2 ? one(n) : fib(n-1) + fib(n-2)
```
and the `::Integer` specification means that it will only be callable when `n` is a subtype of the [abstract](../types/#man-abstract-types) `Integer` type.
Argument-type declarations **normally have no impact on performance**: regardless of what argument types (if any) are declared, Julia compiles a specialized version of the function for the actual argument types passed by the caller. For example, calling `fib(1)` will trigger the compilation of specialized version of `fib` optimized specifically for `Int` arguments, which is then re-used if `fib(7)` or `fib(15)` are called. (There are rare exceptions when an argument-type declaration can trigger additional compiler specializations; see: [Be aware of when Julia avoids specializing](../performance-tips/#Be-aware-of-when-Julia-avoids-specializing).) The most common reasons to declare argument types in Julia are, instead:


## [Argument-type declarations](#Argument-type-declarations)
-   **Dispatch:** As explained in [Methods](../methods/#Methods), you can have different versions ("methods") of a function for different argument types, in which case the argument types are used to determine which implementation is called for which arguments. For example, you might implement a completely different algorithm `fib(x::Number) = ...` that works for any `Number` type by using [Binet's formula](https://en.wikipedia.org/wiki/Fibonacci_number#Binet%27s_formula) to extend it to non-integer values.
-   **Correctness:** Type declarations can be useful if your function only returns correct results for certain argument types. For example, if we omitted argument types and wrote `fib(n) = n ≤ 2 ? one(n) : fib(n-1) + fib(n-2)`, then `fib(1.5)` would silently give us the nonsensical answer `1.0`.
-   **Clarity:** Type declarations can serve as a form of documentation about the expected arguments.


## [Argument-type declarations](#Argument-type-declarations)
However, it is a **common mistake to overly restrict the argument types**, which can unnecessarily limit the applicability of the function and prevent it from being re-used in circumstances you did not anticipate. For example, the `fib(n::Integer)` function above works equally well for `Int` arguments (machine integers) and `BigInt` arbitrary-precision integers (see [BigFloats and BigInts](../../base/numbers/#BigFloats-and-BigInts)), which is especially useful because Fibonacci numbers grow exponentially rapidly and will quickly overflow any fixed-precision type like `Int` (see [Overflow behavior](../integers-and-floating-point-numbers/#Overflow-behavior)). If we had declared our function as `fib(n::Int)`, however, the application to `BigInt` would have been prevented for no reason. In general, you should use the most general applicable abstract types for arguments, and **when in doubt, omit the argument types**. You can always add argument-type specifications later if they become necessary, and you don't sacrifice performance or functionality by omitting them.


## [The return Keyword](#The-return-Keyword)
The value returned by a function is the value of the last expression evaluated, which, by default, is the last expression in the body of the function definition. In the example function, `f`, from the previous section this is the value of the expression `x + y`. As an alternative, as in many other languages, the `return` keyword causes a function to return immediately, providing an expression whose value is returned:
```julia
function g(x, y)
    return x * y
    x + y
end
```
Since function definitions can be entered into interactive sessions, it is easy to compare these definitions:
```julia-repl
julia> f(x, y) = x + y
f (generic function with 1 method)

julia> function g(x, y)
           return x * y
           x + y
       end
g (generic function with 1 method)

julia> f(2, 3)
5

julia> g(2, 3)
6
```
Of course, in a purely linear function body like `g`, the usage of `return` is pointless since the expression `x + y` is never evaluated and we could simply make `x * y` the last expression in the function and omit the `return`. In conjunction with other control flow, however, `return` is of real use. Here, for example, is a function that computes the hypotenuse length of a right triangle with sides of length `x` and `y`, avoiding overflow:


## [The return Keyword](#The-return-Keyword)
```julia-repl
julia> function hypot(x, y)
           x = abs(x)
           y = abs(y)
           if x > y
               r = y/x
               return x*sqrt(1 + r*r)
           end
           if y == 0
               return zero(x)
           end
           r = x/y
           return y*sqrt(1 + r*r)
       end
hypot (generic function with 1 method)

julia> hypot(3, 4)
5.0
```
There are three possible points of return from this function, returning the values of three different expressions, depending on the values of `x` and `y`. The `return` on the last line could be omitted since it is the last expression.


### [Return type](#man-functions-return-type)
A return type can be specified in the function declaration using the `::` operator. This converts the return value to the specified type.
```julia-repl
julia> function g(x, y)::Int8
           return x * y
       end;

julia> typeof(g(1, 2))
Int8
```
This function will always return an `Int8` regardless of the types of `x` and `y`. See [Type Declarations](../types/#Type-Declarations) for more on return types.
Return type declarations are **rarely used** in Julia: in general, you should instead write "type-stable" functions in which Julia's compiler can automatically infer the return type. For more information, see the [Performance Tips](../performance-tips/#man-performance-tips) chapter.


### [Returning nothing](#Returning-nothing)
For functions that do not need to return a value (functions used only for some side effects), the Julia convention is to return the value [`nothing`](../../base/constants/#Core.nothing):
```julia
function printx(x)
    println("x = $x")
    return nothing
end
```
This is a *convention* in the sense that `nothing` is not a Julia keyword but only a singleton object of type `Nothing`. Also, you may notice that the `printx` function example above is contrived, because `println` already returns `nothing`, so that the `return` line is redundant.
There are two possible shortened forms for the `return nothing` expression. On the one hand, the `return` keyword implicitly returns `nothing`, so it can be used alone. On the other hand, since functions implicitly return their last expression evaluated, `nothing` can be used alone when it's the last expression. The preference for the expression `return nothing` as opposed to `return` or `nothing` alone is a matter of coding style.


## [Operators Are Functions](#Operators-Are-Functions)
In Julia, most operators are just functions with support for special syntax. (The exceptions are operators with special evaluation semantics like `&&` and `||`. These operators cannot be functions since [Short-Circuit Evaluation](../control-flow/#Short-Circuit-Evaluation) requires that their operands are not evaluated before evaluation of the operator.) Accordingly, you can also apply them using parenthesized argument lists, just as you would any other function:
```julia-repl
julia> 1 + 2 + 3
6

julia> +(1, 2, 3)
6
```
The infix form is exactly equivalent to the function application form – in fact the former is parsed to produce the function call internally. This also means that you can assign and pass around operators such as [`+`](../../base/math/#Base.:+) and [`*`](../../base/math/#Base.:*-Tuple%7BAny,%20Vararg%7BAny%7D%7D) just like you would with other function values:
```julia-repl
julia> f = +;

julia> f(1, 2, 3)
6
```
Under the name `f`, the function does not support infix notation, however.


## [Operators With Special Names](#Operators-With-Special-Names)
A few special expressions correspond to calls to functions with non-obvious names. These are:
| Expression            | Calls                                                 |
|:----------------------|:------------------------------------------------------|
| `[A B C ...]`         | [`hcat`](../../base/arrays/#Base.hcat)                |
| `[A; B; C; ...]`      | [`vcat`](../../base/arrays/#Base.vcat)                |
| `[A B; C D; ...]`     | [`hvcat`](../../base/arrays/#Base.hvcat)              |
| `[A; B;; C; D;; ...]` | [`hvncat`](../../base/arrays/#Base.hvncat)            |
| `A'`                  | [`adjoint`](../../stdlib/LinearAlgebra/#Base.adjoint) |
| `A[i]`                | [`getindex`](../../base/collections/#Base.getindex)   |
| `A[i] = x`            | [`setindex!`](../../base/collections/#Base.setindex!) |
| `A.n`                 | [`getproperty`](../../base/base/#Base.getproperty)    |
| `A.n = x`             | [`setproperty!`](../../base/base/#Base.setproperty!)  |
Note that expressions similar to `[A; B;; C; D;; ...]` but with more than two consecutive `;` also correspond to `hvncat` calls.


## [Anonymous Functions](#man-anonymous-functions)
Functions in Julia are [first-class objects](https://en.wikipedia.org/wiki/First-class_citizen): they can be assigned to variables, and called using the standard function call syntax from the variable they have been assigned to. They can be used as arguments, and they can be returned as values. They can also be created anonymously, without being given a name, using either of these syntaxes:
```julia-repl
julia> x -> x^2 + 2x - 1
#1 (generic function with 1 method)

julia> function (x)
           x^2 + 2x - 1
       end
#3 (generic function with 1 method)
```
Each statement creates a function taking one argument `x` and returning the value of the polynomial `x^2 + 2x - 1` at that value. Notice that the result is a generic function, but with a compiler-generated name based on consecutive numbering.
The primary use for anonymous functions is passing them to functions which take other functions as arguments. A classic example is [`map`](../../base/collections/#Base.map), which applies a function to each value of an array and returns a new array containing the resulting values:
```julia-repl
julia> map(round, [1.2, 3.5, 1.7])
3-element Vector{Float64}:
 1.0
 4.0
 2.0
```
This is fine if a named function effecting the transform already exists to pass as the first argument to [`map`](../../base/collections/#Base.map). Often, however, a ready-to-use, named function does not exist. In these situations, the anonymous function construct allows easy creation of a single-use function object without needing a name:


## [Anonymous Functions](#man-anonymous-functions)
```julia-repl
julia> map(x -> x^2 + 2x - 1, [1, 3, -1])
3-element Vector{Int64}:
  2
 14
 -2
```
An anonymous function accepting multiple arguments can be written using the syntax `(x,y,z)->2x+y-z`.
Argument-type declarations for anonymous functions work as for named functions, for example `x::Integer->2x`. The return type of an anonymous function cannot be specified.
A zero-argument anonymous function can be written as `()->2+2`. The idea of a function with no arguments may seem strange, but is useful in cases where a result cannot (or should not) be precomputed. For example, Julia has a zero-argument [`time`](../../base/base/#Base.Libc.time-Tuple%7B%7D) function that returns the current time in seconds, and thus `seconds = ()->round(Int, time())` is an anonymous function that returns this time rounded to the nearest integer assigned to the variable `seconds`. Each time this anonymous function is called as `seconds()` the current time will be calculated and returned.


## [Tuples](#Tuples)
Julia has a built-in data structure called a *tuple* that is closely related to function arguments and return values. A tuple is a fixed-length container that can hold any values, but cannot be modified (it is *immutable*). Tuples are constructed with commas and parentheses, and can be accessed via indexing:
```julia-repl
julia> (1, 1+1)
(1, 2)

julia> (1,)
(1,)

julia> x = (0.0, "hello", 6*7)
(0.0, "hello", 42)

julia> x[2]
"hello"
```
Notice that a length-1 tuple must be written with a comma, `(1,)`, since `(1)` would just be a parenthesized value. `()` represents the empty (length-0) tuple.


## [Named Tuples](#Named-Tuples)
The components of tuples can optionally be named, in which case a *named tuple* is constructed:
```julia-repl
julia> x = (a=2, b=1+2)
(a = 2, b = 3)

julia> x[1]
2

julia> x.a
2
```
The fields of named tuples can be accessed by name using dot syntax (`x.a`) in addition to the regular indexing syntax (`x[1]` or `x[:a]`).


## [Destructuring Assignment and Multiple Return Values](#destructuring-assignment)
A comma-separated list of variables (optionally wrapped in parentheses) can appear on the left side of an assignment: the value on the right side is *destructured* by iterating over and assigning to each variable in turn:
```julia-repl
julia> (a, b, c) = 1:3
1:3

julia> b
2
```
The value on the right should be an iterator (see [Iteration interface](../interfaces/#man-interface-iteration)) at least as long as the number of variables on the left (any excess elements of the iterator are ignored).
This can be used to return multiple values from functions by returning a tuple or other iterable value. For example, the following function returns two values:
```julia-repl
julia> function foo(a, b)
           a+b, a*b
       end
foo (generic function with 1 method)
```
If you call it in an interactive session without assigning the return value anywhere, you will see the tuple returned:
```julia-repl
julia> foo(2, 3)
(5, 6)
```
Destructuring assignment extracts each value into a variable:
```julia-repl
julia> x, y = foo(2, 3)
(5, 6)

julia> x
5

julia> y
6
```
Another common use is for swapping variables:
```julia-repl
julia> y, x = x, y
(5, 6)

julia> x
6

julia> y
5
```
If only a subset of the elements of the iterator are required, a common convention is to assign ignored elements to a variable consisting of only underscores `_` (which is an otherwise invalid variable name, see [Allowed Variable Names](../variables/#man-allowed-variable-names)):


## [Destructuring Assignment and Multiple Return Values](#destructuring-assignment)
```julia-repl
julia> _, _, _, d = 1:10
1:10

julia> d
4
```
Other valid left-hand side expressions can be used as elements of the assignment list, which will call [`setindex!`](../../base/collections/#Base.setindex!) or [`setproperty!`](../../base/base/#Base.setproperty!), or recursively destructure individual elements of the iterator:
```julia-repl
julia> X = zeros(3);

julia> X[1], (a, b) = (1, (2, 3))
(1, (2, 3))

julia> X
3-element Vector{Float64}:
 1.0
 0.0
 0.0

julia> a
2

julia> b
3
```
`...` with assignment requires Julia 1.6
If the last symbol in the assignment list is suffixed by `...` (known as *slurping*), then it will be assigned a collection or lazy iterator of the remaining elements of the right-hand side iterator:
```julia-repl
julia> a, b... = "hello"
"hello"

julia> a
'h': ASCII/Unicode U+0068 (category Ll: Letter, lowercase)

julia> b
"ello"

julia> a, b... = Iterators.map(abs2, 1:4)
Base.Generator{UnitRange{Int64}, typeof(abs2)}(abs2, 1:4)

julia> a
1

julia> b
Base.Iterators.Rest{Base.Generator{UnitRange{Int64}, typeof(abs2)}, Int64}(Base.Generator{UnitRange{Int64}, typeof(abs2)}(abs2, 1:4), 1)
```
See [`Base.rest`](../../base/collections/#Base.rest) for details on the precise handling and customization for specific iterators.
`...` in non-final position of an assignment requires Julia 1.9
Slurping in assignments can also occur in any other position. As opposed to slurping the end of a collection however, this will always be eager.


## [Destructuring Assignment and Multiple Return Values](#destructuring-assignment)
```julia-repl
julia> a, b..., c = 1:5
1:5

julia> a
1

julia> b
3-element Vector{Int64}:
 2
 3
 4

julia> c
5

julia> front..., tail = "Hi!"
"Hi!"

julia> front
"Hi"

julia> tail
'!': ASCII/Unicode U+0021 (category Po: Punctuation, other)
```
This is implemented in terms of the function [`Base.split_rest`](../../base/collections/#Base.split_rest).
Note that for variadic function definitions, slurping is still only allowed in final position. This does not apply to [single argument destructuring](#man-argument-destructuring) though, as that does not affect method dispatch:
```julia-repl
julia> f(x..., y) = x
ERROR: syntax: invalid "..." on non-final argument
Stacktrace:
[...]

julia> f((x..., y)) = x
f (generic function with 1 method)

julia> f((1, 2, 3))
(1, 2)
```


## [Property destructuring](#Property-destructuring)
Instead of destructuring based on iteration, the right side of assignments can also be destructured using property names. This follows the syntax for NamedTuples, and works by assigning to each variable on the left a property of the right side of the assignment with the same name using `getproperty`:
```julia-repl
julia> (; b, a) = (a=1, b=2, c=3)
(a = 1, b = 2, c = 3)

julia> a
1

julia> b
2
```


## [Argument destructuring](#man-argument-destructuring)
The destructuring feature can also be used within a function argument. If a function argument name is written as a tuple (e.g. `(x, y)`) instead of just a symbol, then an assignment `(x, y) = argument` will be inserted for you:
```julia-repl
julia> minmax(x, y) = (y < x) ? (y, x) : (x, y)

julia> gap((min, max)) = max - min

julia> gap(minmax(10, 2))
8
```
Notice the extra set of parentheses in the definition of `gap`. Without those, `gap` would be a two-argument function, and this example would not work.
Similarly, property destructuring can also be used for function arguments:
```julia-repl
julia> foo((; x, y)) = x + y
foo (generic function with 1 method)

julia> foo((x=1, y=2))
3

julia> struct A
           x
           y
       end

julia> foo(A(3, 4))
7
```
For anonymous functions, destructuring a single argument requires an extra comma:
```julia
julia> map(((x, y),) -> x + y, [(1, 2), (3, 4)])
2-element Array{Int64,1}:
 3
 7
```


## [Varargs Functions](#Varargs-Functions)
It is often convenient to be able to write functions taking an arbitrary number of arguments. Such functions are traditionally known as "varargs" functions, which is short for "variable number of arguments". You can define a varargs function by following the last positional argument with an ellipsis:
```julia-repl
julia> bar(a, b, x...) = (a, b, x)
bar (generic function with 1 method)
```
The variables `a` and `b` are bound to the first two argument values as usual, and the variable `x` is bound to an iterable collection of the zero or more values passed to `bar` after its first two arguments:
```julia-repl
julia> bar(1, 2)
(1, 2, ())

julia> bar(1, 2, 3)
(1, 2, (3,))

julia> bar(1, 2, 3, 4)
(1, 2, (3, 4))

julia> bar(1, 2, 3, 4, 5, 6)
(1, 2, (3, 4, 5, 6))
```
In all these cases, `x` is bound to a tuple of the trailing values passed to `bar`.
It is possible to constrain the number of values passed as a variable argument; this will be discussed later in [Parametrically-constrained Varargs methods](../methods/#Parametrically-constrained-Varargs-methods).
On the flip side, it is often handy to "splat" the values contained in an iterable collection into a function call as individual arguments. To do this, one also uses `...` but in the function call instead:
```julia-repl
julia> x = (3, 4)
(3, 4)

julia> bar(1, 2, x...)
(1, 2, (3, 4))
```
In this case a tuple of values is spliced into a varargs call precisely where the variable number of arguments go. This need not be the case, however:


## [Varargs Functions](#Varargs-Functions)
```julia-repl
julia> x = (2, 3, 4)
(2, 3, 4)

julia> bar(1, x...)
(1, 2, (3, 4))

julia> x = (1, 2, 3, 4)
(1, 2, 3, 4)

julia> bar(x...)
(1, 2, (3, 4))
```
Furthermore, the iterable object splatted into a function call need not be a tuple:
```julia-repl
julia> x = [3, 4]
2-element Vector{Int64}:
 3
 4

julia> bar(1, 2, x...)
(1, 2, (3, 4))

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

julia> bar(x...)
(1, 2, (3, 4))
```
Also, the function that arguments are splatted into need not be a varargs function (although it often is):
```julia-repl
julia> baz(a, b) = a + b;

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

julia> baz(args...)
3

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

julia> baz(args...)
ERROR: MethodError: no method matching baz(::Int64, ::Int64, ::Int64)
The function `baz` exists, but no method is defined for this combination of argument types.

Closest candidates are:
  baz(::Any, ::Any)
   @ Main none:1

Stacktrace:
[...]
```
As you can see, if the wrong number of elements are in the splatted container, then the function call will fail, just as it would if too many arguments were given explicitly.


## [Optional Arguments](#Optional-Arguments)
It is often possible to provide sensible default values for function arguments. This can save users from having to pass every argument on every call. For example, the function [`Date(y, [m, d])`](../../stdlib/Dates/#Dates.Date) from `Dates` module constructs a `Date` type for a given year `y`, month `m` and day `d`. However, `m` and `d` arguments are optional and their default value is `1`. This behavior can be expressed concisely as:
```julia-repl
julia> using Dates

julia> function date(y::Int64, m::Int64=1, d::Int64=1)
           err = Dates.validargs(Date, y, m, d)
           err === nothing || throw(err)
           return Date(Dates.UTD(Dates.totaldays(y, m, d)))
       end
date (generic function with 3 methods)
```
Observe, that this definition calls another method of the `Date` function that takes one argument of type `UTInstant{Day}`.
With this definition, the function can be called with either one, two or three arguments, and `1` is automatically passed when only one or two of the arguments are specified:
```julia-repl
julia> date(2000, 12, 12)
2000-12-12

julia> date(2000, 12)
2000-12-01

julia> date(2000)
2000-01-01
```
Optional arguments are actually just a convenient syntax for writing multiple method definitions with different numbers of arguments (see [Note on Optional and keyword Arguments](../methods/#Note-on-Optional-and-keyword-Arguments)). This can be checked for our `date` function example by calling the `methods` function:


## [Optional Arguments](#Optional-Arguments)
```julia-repl
julia> methods(date)
# 3 methods for generic function "date":
[1] date(y::Int64) in Main at REPL[1]:1
[2] date(y::Int64, m::Int64) in Main at REPL[1]:1
[3] date(y::Int64, m::Int64, d::Int64) in Main at REPL[1]:1
```


## [Keyword Arguments](#Keyword-Arguments)
Some functions need a large number of arguments, or have a large number of behaviors. Remembering how to call such functions can be difficult. Keyword arguments can make these complex interfaces easier to use and extend by allowing arguments to be identified by name instead of only by position.
For example, consider a function `plot` that plots a line. This function might have many options, for controlling line style, width, color, and so on. If it accepts keyword arguments, a possible call might look like `plot(x, y, width=2)`, where we have chosen to specify only line width. Notice that this serves two purposes. The call is easier to read, since we can label an argument with its meaning. It also becomes possible to pass any subset of a large number of arguments, in any order.
Functions with keyword arguments are defined using a semicolon in the signature:
```julia
function plot(x, y; style="solid", width=1, color="black")
    ###
end
```
When the function is called, the semicolon is optional: one can either call `plot(x, y, width=2)` or `plot(x, y; width=2)`, but the former style is more common. An explicit semicolon is required only for passing varargs or computed keywords as described below.
Keyword argument default values are evaluated only when necessary (when a corresponding keyword argument is not passed), and in left-to-right order. Therefore default expressions may refer to prior keyword arguments.
The types of keyword arguments can be made explicit as follows:
```julia
function f(; x::Int=1)
    ###
end
```


## [Keyword Arguments](#Keyword-Arguments)
Keyword arguments can also be used in varargs functions:
```julia
function plot(x...; style="solid")
    ###
end
```
Extra keyword arguments can be collected using `...`, as in varargs functions:
```julia
function f(x; y=0, kwargs...)
    ###
end
```
Inside `f`, `kwargs` will be an immutable key-value iterator over a named tuple. Named tuples (as well as dictionaries with keys of `Symbol`, and other iterators yielding two-value collections with symbol as first values) can be passed as keyword arguments using a semicolon in a call, e.g. `f(x, z=1; kwargs...)`.
If a keyword argument is not assigned a default value in the method definition, then it is *required*: an [`UndefKeywordError`](../../base/base/#Core.UndefKeywordError) exception will be thrown if the caller does not assign it a value:
```julia
function f(x; y)
    ###
end
f(3, y=5) # ok, y is assigned
f(3)      # throws UndefKeywordError(:y)
```
One can also pass `key => value` expressions after a semicolon. For example, `plot(x, y; :width => 2)` is equivalent to `plot(x, y, width=2)`. This is useful in situations where the keyword name is computed at runtime.
When a bare identifier or dot expression occurs after a semicolon, the keyword argument name is implied by the identifier or field name. For example `plot(x, y; width)` is equivalent to `plot(x, y; width=width)` and `plot(x, y; options.width)` is equivalent to `plot(x, y; width=options.width)`.


## [Keyword Arguments](#Keyword-Arguments)
The nature of keyword arguments makes it possible to specify the same argument more than once. For example, in the call `plot(x, y; options..., width=2)` it is possible that the `options` structure also contains a value for `width`. In such a case the rightmost occurrence takes precedence; in this example, `width` is certain to have the value `2`. However, explicitly specifying the same keyword argument multiple times, for example `plot(x, y, width=2, width=3)`, is not allowed and results in a syntax error.


## [Evaluation Scope of Default Values](#Evaluation-Scope-of-Default-Values)
When optional and keyword argument default expressions are evaluated, only *previous* arguments are in scope. For example, given this definition:
```julia
function f(x, a=b, b=1)
    ###
end
```
the `b` in `a=b` refers to a `b` in an outer scope, not the subsequent argument `b`.


## [Do-Block Syntax for Function Arguments](#Do-Block-Syntax-for-Function-Arguments)
Passing functions as arguments to other functions is a powerful technique, but the syntax for it is not always convenient. Such calls are especially awkward to write when the function argument requires multiple lines. As an example, consider calling [`map`](../../base/collections/#Base.map) on a function with several cases:
```julia
map(x->begin
           if x < 0 && iseven(x)
               return 0
           elseif x == 0
               return 1
           else
               return x
           end
       end,
    [A, B, C])
```
Julia provides a reserved word `do` for rewriting this code more clearly:
```julia
map([A, B, C]) do x
    if x < 0 && iseven(x)
        return 0
    elseif x == 0
        return 1
    else
        return x
    end
end
```
The `do x` syntax creates an anonymous function with argument `x` and passes the anonymous function as the first argument to the "outer" function - [`map`](../../base/collections/#Base.map) in this example. Similarly, `do a,b` would create a two-argument anonymous function. Note that `do (a,b)` would create a one-argument anonymous function, whose argument is a tuple to be deconstructed. A plain `do` would declare that what follows is an anonymous function of the form `() -> ...`.
How these arguments are initialized depends on the "outer" function; here, [`map`](../../base/collections/#Base.map) will sequentially set `x` to `A`, `B`, `C`, calling the anonymous function on each, just as would happen in the syntax `map(func, [A, B, C])`.


## [Do-Block Syntax for Function Arguments](#Do-Block-Syntax-for-Function-Arguments)
This syntax makes it easier to use functions to effectively extend the language, since calls look like normal code blocks. There are many possible uses quite different from [`map`](../../base/collections/#Base.map), such as managing system state. For example, there is a version of [`open`](../../base/io-network/#Base.open) that runs code ensuring that the opened file is eventually closed:
```julia
open("outfile", "w") do io
    write(io, data)
end
```
This is accomplished by the following definition:
```julia
function open(f::Function, args...)
    io = open(args...)
    try
        f(io)
    finally
        close(io)
    end
end
```
Here, [`open`](../../base/io-network/#Base.open) first opens the file for writing and then passes the resulting output stream to the anonymous function you defined in the `do ... end` block. After your function exits, [`open`](../../base/io-network/#Base.open) will make sure that the stream is properly closed, regardless of whether your function exited normally or threw an exception. (The `try/finally` construct will be described in [Control Flow](../control-flow/#Control-Flow).)
With the `do` block syntax, it helps to check the documentation or implementation to know how the arguments of the user function are initialized.


## [Do-Block Syntax for Function Arguments](#Do-Block-Syntax-for-Function-Arguments)
A `do` block, like any other inner function, can "capture" variables from its enclosing scope. For example, the variable `data` in the above example of `open...do` is captured from the outer scope. Captured variables can create performance challenges as discussed in [performance tips](../performance-tips/#man-performance-captured).


## [Function composition and piping](#Function-composition-and-piping)
Functions in Julia can be combined by composing or piping (chaining) them together.
Function composition is when you combine functions together and apply the resulting composition to arguments. You use the function composition operator (`∘`) to compose the functions, so `(f ∘ g)(args...; kw...)` is the same as `f(g(args...; kw...))`.
You can type the composition operator at the REPL and suitably-configured editors using `\circ<tab>`.
For example, the `sqrt` and `+` functions can be composed like this:
```julia-repl
julia> (sqrt ∘ +)(3, 6)
3.0
```
This adds the numbers first, then finds the square root of the result.
The next example composes three functions and maps the result over an array of strings:
```julia-repl
julia> map(first ∘ reverse ∘ uppercase, split("you can compose functions like this"))
6-element Vector{Char}:
 'U': ASCII/Unicode U+0055 (category Lu: Letter, uppercase)
 'N': ASCII/Unicode U+004E (category Lu: Letter, uppercase)
 'E': ASCII/Unicode U+0045 (category Lu: Letter, uppercase)
 'S': ASCII/Unicode U+0053 (category Lu: Letter, uppercase)
 'E': ASCII/Unicode U+0045 (category Lu: Letter, uppercase)
 'S': ASCII/Unicode U+0053 (category Lu: Letter, uppercase)
```
Function chaining (sometimes called "piping" or "using a pipe" to send data to a subsequent function) is when you apply a function to the previous function's output:
```julia-repl
julia> 1:10 |> sum |> sqrt
7.416198487095663
```


## [Function composition and piping](#Function-composition-and-piping)
Here, the total produced by `sum` is passed to the `sqrt` function. The equivalent composition would be:
```julia-repl
julia> (sqrt ∘ sum)(1:10)
7.416198487095663
```
The pipe operator can also be used with broadcasting, as `.|>`, to provide a useful combination of the chaining/piping and dot vectorization syntax (described below).
```julia-repl
julia> ["a", "list", "of", "strings"] .|> [uppercase, reverse, titlecase, length]
4-element Vector{Any}:
  "A"
  "tsil"
  "Of"
 7
```
When combining pipes with anonymous functions, parentheses must be used if subsequent pipes are not to be parsed as part of the anonymous function's body. Compare:
```julia-repl
julia> 1:3 .|> (x -> x^2) |> sum |> sqrt
3.7416573867739413

julia> 1:3 .|> x -> x^2 |> sum |> sqrt
3-element Vector{Float64}:
 1.0
 2.0
 3.0
```


## [Dot Syntax for Vectorizing Functions](#man-vectorized)
In technical-computing languages, it is common to have "vectorized" versions of functions, which simply apply a given function `f(x)` to each element of an array `A` to yield a new array via `f(A)`. This kind of syntax is convenient for data processing, but in other languages vectorization is also often required for performance: if loops are slow, the "vectorized" version of a function can call fast library code written in a low-level language. In Julia, vectorized functions are *not* required for performance, and indeed it is often beneficial to write your own loops (see [Performance Tips](../performance-tips/#man-performance-tips)), but they can still be convenient. Therefore, *any* Julia function `f` can be applied elementwise to any array (or other collection) with the syntax `f.(A)`. For example, `sin` can be applied to all elements in the vector `A` like so:
```julia-repl
julia> A = [1.0, 2.0, 3.0]
3-element Vector{Float64}:
 1.0
 2.0
 3.0

julia> sin.(A)
3-element Vector{Float64}:
 0.8414709848078965
 0.9092974268256817
 0.1411200080598672
```
Of course, you can omit the dot if you write a specialized "vector" method of `f`, e.g. via `f(A::AbstractArray) = map(f, A)`, and this is just as efficient as `f.(A)`. The advantage of the `f.(A)` syntax is that which functions are vectorizable need not be decided upon in advance by the library writer.


## [Dot Syntax for Vectorizing Functions](#man-vectorized)
More generally, `f.(args...)` is actually equivalent to `broadcast(f, args...)`, which allows you to operate on multiple arrays (even of different shapes), or a mix of arrays and scalars (see [Broadcasting](../arrays/#Broadcasting)). For example, if you have `f(x, y) = 3x + 4y`, then `f.(pi, A)` will return a new array consisting of `f(pi,a)` for each `a` in `A`, and `f.(vector1, vector2)` will return a new vector consisting of `f(vector1[i], vector2[i])` for each index `i` (throwing an exception if the vectors have different length).
```julia-repl
julia> f(x, y) = 3x + 4y;

julia> A = [1.0, 2.0, 3.0];

julia> B = [4.0, 5.0, 6.0];

julia> f.(pi, A)
3-element Vector{Float64}:
 13.42477796076938
 17.42477796076938
 21.42477796076938

julia> f.(A, B)
3-element Vector{Float64}:
 19.0
 26.0
 33.0
```
Keyword arguments are not broadcasted over, but are simply passed through to each call of the function. For example, `round.(x, digits=3)` is equivalent to `broadcast(x -> round(x, digits=3), x)`.


## [Dot Syntax for Vectorizing Functions](#man-vectorized)
Moreover, *nested* `f.(args...)` calls are *fused* into a single `broadcast` loop. For example, `sin.(cos.(X))` is equivalent to `broadcast(x -> sin(cos(x)), X)`, similar to `[sin(cos(x)) for x in X]`: there is only a single loop over `X`, and a single array is allocated for the result. \[In contrast, `sin(cos(X))` in a typical "vectorized" language would first allocate one temporary array for `tmp=cos(X)`, and then compute `sin(tmp)` in a separate loop, allocating a second array.\] This loop fusion is not a compiler optimization that may or may not occur, it is a *syntactic guarantee* whenever nested `f.(args...)` calls are encountered. Technically, the fusion stops as soon as a "non-dot" function call is encountered; for example, in `sin.(sort(cos.(X)))` the `sin` and `cos` loops cannot be merged because of the intervening `sort` function.


## [Dot Syntax for Vectorizing Functions](#man-vectorized)
Finally, the maximum efficiency is typically achieved when the output array of a vectorized operation is *pre-allocated*, so that repeated calls do not allocate new arrays over and over again for the results (see [Pre-allocating outputs](../performance-tips/#Pre-allocating-outputs)). A convenient syntax for this is `X .= ...`, which is equivalent to `broadcast!(identity, X, ...)` except that, as above, the `broadcast!` loop is fused with any nested "dot" calls. For example, `X .= sin.(Y)` is equivalent to `broadcast!(sin, X, Y)`, overwriting `X` with `sin.(Y)` in-place. If the left-hand side is an array-indexing expression, e.g. `X[begin+1:end] .= sin.(Y)`, then it translates to `broadcast!` on a `view`, e.g. `broadcast!(sin, view(X, firstindex(X)+1:lastindex(X)), Y)`, so that the left-hand side is updated in-place.
Since adding dots to many operations and function calls in an expression can be tedious and lead to code that is difficult to read, the macro [`@.`](../../base/arrays/#Base.Broadcast.@__dot__) is provided to convert *every* function call, operation, and assignment in an expression into the "dotted" version.
```julia-repl
julia> Y = [1.0, 2.0, 3.0, 4.0];

julia> X = similar(Y); # pre-allocate output array

julia> @. X = sin(cos(Y)) # equivalent to X .= sin.(cos.(Y))
4-element Vector{Float64}:
  0.5143952585235492
 -0.4042391538522658
 -0.8360218615377305
 -0.6080830096407656
```


## [Dot Syntax for Vectorizing Functions](#man-vectorized)
Binary (or unary) operators like `.+` are handled with the same mechanism: they are equivalent to `broadcast` calls and are fused with other nested "dot" calls. `X .+= Y` etcetera is equivalent to `X .= X .+ Y` and results in a fused in-place assignment; see also [dot operators](../mathematical-operations/#man-dot-operators).
You can also combine dot operations with function chaining using [`|>`](../../base/base/#Base.:%7C%3E), as in this example:
```julia-repl
julia> 1:5 .|> [x->x^2, inv, x->2*x, -, isodd]
5-element Vector{Real}:
    1
    0.5
    6
   -4
 true
```
All functions in the fused broadcast are always called for every element of the result. Thus `X .+ σ .* randn.()` will add a mask of independent and identically sampled random values to each element of the array `X`, but `X .+ σ .* randn()` will add the *same* random sample to each element. In cases where the fused computation is constant along one or more axes of the broadcast iteration, it may be possible to leverage a space-time tradeoff and allocate intermediate values to reduce the number of computations. See more at [performance tips](../performance-tips/#man-performance-unfuse).


## [Further Reading](#Further-Reading)
We should mention here that this is far from a complete picture of defining functions. Julia has a sophisticated type system and allows multiple dispatch on argument types. None of the examples given here provide any type annotations on their arguments, meaning that they are applicable to all types of arguments. The type system is described in [Types](../types/#man-types) and defining a function in terms of methods chosen by multiple dispatch on run-time argument types is described in [Methods](../methods/#Methods).
------------------------------------------------------------------------


# Control Flow · The Julia Language
Source: https://docs.julialang.org/en/v1/manual/control-flow/


# [Control Flow](#Control-Flow)
Julia provides a variety of control flow constructs:
-   [Compound Expressions](#man-compound-expressions): `begin` and `;`.
-   [Conditional Evaluation](#man-conditional-evaluation): `if`-`elseif`-`else` and `?:` (ternary operator).
-   [Short-Circuit Evaluation](#Short-Circuit-Evaluation): logical operators `&&` (“and”) and `||` (“or”), and also chained comparisons.
-   [Repeated Evaluation: Loops](#man-loops): `while` and `for`.
-   [Exception Handling](#Exception-Handling): `try`-`catch`, [`error`](../../base/base/#Base.error) and [`throw`](../../base/base/#Core.throw).
-   [Tasks (aka Coroutines)](#man-tasks): [`yieldto`](../../base/parallel/#Base.yieldto).
The first five control flow mechanisms are standard to high-level programming languages. [`Task`](../../base/parallel/#Core.Task)s are not so standard: they provide non-local control flow, making it possible to switch between temporarily-suspended computations. This is a powerful construct: both exception handling and cooperative multitasking are implemented in Julia using tasks. Everyday programming requires no direct usage of tasks, but certain problems can be solved much more easily by using tasks.


## [Compound Expressions](#man-compound-expressions)
Sometimes it is convenient to have a single expression which evaluates several subexpressions in order, returning the value of the last subexpression as its value. There are two Julia constructs that accomplish this: `begin` blocks and `;` chains. The value of both compound expression constructs is that of the last subexpression. Here's an example of a `begin` block:
```julia-repl
julia> z = begin
           x = 1
           y = 2
           x + y
       end
3
```
Since these are fairly small, simple expressions, they could easily be placed onto a single line, which is where the `;` chain syntax comes in handy:
```julia-repl
julia> z = (x = 1; y = 2; x + y)
3
```
This syntax is particularly useful with the terse single-line function definition form introduced in [Functions](../functions/#man-functions). Although it is typical, there is no requirement that `begin` blocks be multiline or that `;` chains be single-line:
```julia-repl
julia> begin x = 1; y = 2; x + y end
3

julia> (x = 1;
        y = 2;
        x + y)
3
```


## [Conditional Evaluation](#man-conditional-evaluation)
Conditional evaluation allows portions of code to be evaluated or not evaluated depending on the value of a boolean expression. Here is the anatomy of the `if`-`elseif`-`else` conditional syntax:
```julia
if x < y
    println("x is less than y")
elseif x > y
    println("x is greater than y")
else
    println("x is equal to y")
end
```
If the condition expression `x < y` is `true`, then the corresponding block is evaluated; otherwise the condition expression `x > y` is evaluated, and if it is `true`, the corresponding block is evaluated; if neither expression is true, the `else` block is evaluated. Here it is in action:
```julia-repl
julia> function test(x, y)
           if x < y
               println("x is less than y")
           elseif x > y
               println("x is greater than y")
           else
               println("x is equal to y")
           end
       end
test (generic function with 1 method)

julia> test(1, 2)
x is less than y

julia> test(2, 1)
x is greater than y

julia> test(1, 1)
x is equal to y
```
The `elseif` and `else` blocks are optional, and as many `elseif` blocks as desired can be used. The condition expressions in the `if`-`elseif`-`else` construct are evaluated until the first one evaluates to `true`, after which the associated block is evaluated, and no further condition expressions or blocks are evaluated.


## [Conditional Evaluation](#man-conditional-evaluation)
`if` blocks are "leaky", i.e. they do not introduce a local scope. This means that new variables defined inside the `if` clauses can be used after the `if` block, even if they weren't defined before. So, we could have defined the `test` function above as
```julia-repl
julia> function test(x,y)
           if x < y
               relation = "less than"
           elseif x == y
               relation = "equal to"
           else
               relation = "greater than"
           end
           println("x is ", relation, " y.")
       end
test (generic function with 1 method)

julia> test(2, 1)
x is greater than y.
```
The variable `relation` is declared inside the `if` block, but used outside. However, when depending on this behavior, make sure all possible code paths define a value for the variable. The following change to the above function results in a runtime error
```julia-repl
julia> function test(x,y)
           if x < y
               relation = "less than"
           elseif x == y
               relation = "equal to"
           end
           println("x is ", relation, " y.")
       end
test (generic function with 1 method)

julia> test(1,2)
x is less than y.

julia> test(2,1)
ERROR: UndefVarError: `relation` not defined in local scope
Stacktrace:
 [1] test(::Int64, ::Int64) at ./none:7
```
`if` blocks also return a value, which may seem unintuitive to users coming from many other languages. This value is simply the return value of the last executed statement in the branch that was chosen, so


## [Conditional Evaluation](#man-conditional-evaluation)
```julia-repl
julia> x = 3
3

julia> if x > 0
           "positive!"
       else
           "negative..."
       end
"positive!"
```
Note that very short conditional statements (one-liners) are frequently expressed using Short-Circuit Evaluation in Julia, as outlined in the next section.
Unlike C, MATLAB, Perl, Python, and Ruby – but like Java, and a few other stricter, typed languages – it is an error if the value of a conditional expression is anything but `true` or `false`:
```julia-repl
julia> if 1
           println("true")
       end
ERROR: TypeError: non-boolean (Int64) used in boolean context
```
This error indicates that the conditional was of the wrong type: [`Int64`](../../base/numbers/#Core.Int64) rather than the required [`Bool`](../../base/numbers/#Core.Bool).
The so-called "ternary operator", `?:`, is closely related to the `if`-`elseif`-`else` syntax, but is used where a conditional choice between single expression values is required, as opposed to conditional execution of longer blocks of code. It gets its name from being the only operator in most languages taking three operands:
```julia
a ? b : c
```
The expression `a`, before the `?`, is a condition expression, and the ternary operation evaluates the expression `b`, before the `:`, if the condition `a` is `true` or the expression `c`, after the `:`, if it is `false`. Note that the spaces around `?` and `:` are mandatory: an expression like `a?b:c` is not a valid ternary expression (but a newline is acceptable after both the `?` and the `:`).


## [Conditional Evaluation](#man-conditional-evaluation)
The easiest way to understand this behavior is to see an example. In the previous example, the `println` call is shared by all three branches: the only real choice is which literal string to print. This could be written more concisely using the ternary operator. For the sake of clarity, let's try a two-way version first:
```julia-repl
julia> x = 1; y = 2;

julia> println(x < y ? "less than" : "not less than")
less than

julia> x = 1; y = 0;

julia> println(x < y ? "less than" : "not less than")
not less than
```
If the expression `x < y` is true, the entire ternary operator expression evaluates to the string `"less than"` and otherwise it evaluates to the string `"not less than"`. The original three-way example requires chaining multiple uses of the ternary operator together:
```julia-repl
julia> test(x, y) = println(x < y ? "x is less than y"    :
                            x > y ? "x is greater than y" : "x is equal to y")
test (generic function with 1 method)

julia> test(1, 2)
x is less than y

julia> test(2, 1)
x is greater than y

julia> test(1, 1)
x is equal to y
```
To facilitate chaining, the operator associates from right to left.
It is significant that like `if`-`elseif`-`else`, the expressions before and after the `:` are only evaluated if the condition expression evaluates to `true` or `false`, respectively:
```julia-repl
julia> v(x) = (println(x); x)
v (generic function with 1 method)

julia> 1 < 2 ? v("yes") : v("no")
yes
"yes"

julia> 1 > 2 ? v("yes") : v("no")
no
"no"
```


## [Short-Circuit Evaluation](#Short-Circuit-Evaluation)
The `&&` and `||` operators in Julia correspond to logical “and” and “or” operations, respectively, and are typically used for this purpose. However, they have an additional property of *short-circuit* evaluation: they don't necessarily evaluate their second argument, as explained below. (There are also bitwise `&` and `|` operators that can be used as logical “and” and “or” *without* short-circuit behavior, but beware that `&` and `|` have higher precedence than `&&` and `||` for evaluation order.)
Short-circuit evaluation is quite similar to conditional evaluation. The behavior is found in most imperative programming languages having the `&&` and `||` boolean operators: in a series of boolean expressions connected by these operators, only the minimum number of expressions are evaluated as are necessary to determine the final boolean value of the entire chain. Some languages (like Python) refer to them as `and` (`&&`) and `or` (`||`). Explicitly, this means that:
-   In the expression `a && b`, the subexpression `b` is only evaluated if `a` evaluates to `true`.
-   In the expression `a || b`, the subexpression `b` is only evaluated if `a` evaluates to `false`.
The reasoning is that `a && b` must be `false` if `a` is `false`, regardless of the value of `b`, and likewise, the value of `a || b` must be true if `a` is `true`, regardless of the value of `b`. Both `&&` and `||` associate to the right, but `&&` has higher precedence than `||` does. It's easy to experiment with this behavior:


## [Short-Circuit Evaluation](#Short-Circuit-Evaluation)
```julia-repl
julia> t(x) = (println(x); true)
t (generic function with 1 method)

julia> f(x) = (println(x); false)
f (generic function with 1 method)

julia> t(1) && t(2)
1
2
true

julia> t(1) && f(2)
1
2
false

julia> f(1) && t(2)
1
false

julia> f(1) && f(2)
1
false

julia> t(1) || t(2)
1
true

julia> t(1) || f(2)
1
true

julia> f(1) || t(2)
1
2
true

julia> f(1) || f(2)
1
2
false
```
You can easily experiment in the same way with the associativity and precedence of various combinations of `&&` and `||` operators.
This behavior is frequently used in Julia to form an alternative to very short `if` statements. Instead of `if <cond> <statement> end`, one can write `<cond> && <statement>` (which could be read as: \<cond> *and then* \<statement>). Similarly, instead of `if ! <cond> <statement> end`, one can write `<cond> || <statement>` (which could be read as: \<cond> *or else* \<statement>).
For example, a recursive factorial routine could be defined like this:
```julia-repl
julia> function fact(n::Int)
           n >= 0 || error("n must be non-negative")
           n == 0 && return 1
           n * fact(n-1)
       end
fact (generic function with 1 method)

julia> fact(5)
120

julia> fact(0)
1

julia> fact(-1)
ERROR: n must be non-negative
Stacktrace:
 [1] error at ./error.jl:33 [inlined]
 [2] fact(::Int64) at ./none:2
 [3] top-level scope
```


## [Short-Circuit Evaluation](#Short-Circuit-Evaluation)
Boolean operations *without* short-circuit evaluation can be done with the bitwise boolean operators introduced in [Mathematical Operations and Elementary Functions](../mathematical-operations/#Mathematical-Operations-and-Elementary-Functions): `&` and `|`. These are normal functions, which happen to support infix operator syntax, but always evaluate their arguments:
```julia-repl
julia> f(1) & t(2)
1
2
false

julia> t(1) | t(2)
1
2
true
```
Just like condition expressions used in `if`, `elseif` or the ternary operator, the operands of `&&` or `||` must be boolean values (`true` or `false`). Using a non-boolean value anywhere except for the last entry in a conditional chain is an error:
```julia-repl
julia> 1 && true
ERROR: TypeError: non-boolean (Int64) used in boolean context
```
On the other hand, any type of expression can be used at the end of a conditional chain. It will be evaluated and returned depending on the preceding conditionals:
```julia-repl
julia> true && (x = (1, 2, 3))
(1, 2, 3)

julia> false && (x = (1, 2, 3))
false
```


## [Repeated Evaluation: Loops](#man-loops)
There are two constructs for repeated evaluation of expressions: the `while` loop and the `for` loop. Here is an example of a `while` loop:
```julia-repl
julia> i = 1;

julia> while i <= 3
           println(i)
           global i += 1
       end
1
2
3
```
The `while` loop evaluates the condition expression (`i <= 3` in this case), and as long it remains `true`, keeps also evaluating the body of the `while` loop. If the condition expression is `false` when the `while` loop is first reached, the body is never evaluated.
The `for` loop makes common repeated evaluation idioms easier to write. Since counting up and down like the above `while` loop does is so common, it can be expressed more concisely with a `for` loop:
```julia-repl
julia> for i = 1:3
           println(i)
       end
1
2
3
```
Here the `1:3` is a [`range`](../../base/math/#Base.range) object, representing the sequence of numbers 1, 2, 3. The `for` loop iterates through these values, assigning each one in turn to the variable `i`. In general, the `for` construct can loop over any "iterable" object (or "container"), from a range like `1:3` or `1:3:13` (a [`StepRange`](../../base/collections/#Base.StepRange) indicating every 3rd integer 1, 4, 7, …, 13) to more generic containers like arrays, including [iterators defined by user code](../interfaces/#man-interface-iteration) or external packages. For containers other than ranges, the alternative (but fully equivalent) keyword `in` or `∈` is typically used instead of `=`, since it makes the code read more clearly:


## [Repeated Evaluation: Loops](#man-loops)
```julia-repl
julia> for i in [1,4,0]
           println(i)
       end
1
4
0

julia> for s ∈ ["foo","bar","baz"]
           println(s)
       end
foo
bar
baz
```
Various types of iterable containers will be introduced and discussed in later sections of the manual (see, e.g., [Multi-dimensional Arrays](../arrays/#man-multi-dim-arrays)).
One rather important distinction between the previous `while` loop form and the `for` loop form is the scope during which the variable is visible. A `for` loop always introduces a new iteration variable in its body, regardless of whether a variable of the same name exists in the enclosing scope. This implies that on the one hand `i` need not be declared before the loop. On the other hand it will not be visible outside the loop, nor will an outside variable of the same name be affected. You'll either need a new interactive session instance or a different variable name to test this:
```julia-repl
julia> for j = 1:3
           println(j)
       end
1
2
3

julia> j
ERROR: UndefVarError: `j` not defined in `Main`
```
```julia-repl
julia> j = 0;

julia> for j = 1:3
           println(j)
       end
1
2
3

julia> j
0
```
Use `for outer` to modify the latter behavior and reuse an existing local variable.
See [Scope of Variables](../variables-and-scoping/#scope-of-variables) for a detailed explanation of variable scope, [`outer`](../../base/base/#outer), and how it works in Julia.


## [Repeated Evaluation: Loops](#man-loops)
It is sometimes convenient to terminate the repetition of a `while` before the test condition is falsified or stop iterating in a `for` loop before the end of the iterable object is reached. This can be accomplished with the `break` keyword:
```julia-repl
julia> i = 1;

julia> while true
           println(i)
           if i >= 3
               break
           end
           global i += 1
       end
1
2
3

julia> for j = 1:1000
           println(j)
           if j >= 3
               break
           end
       end
1
2
3
```
Without the `break` keyword, the above `while` loop would never terminate on its own, and the `for` loop would iterate up to 1000. These loops are both exited early by using `break`.
In other circumstances, it is handy to be able to stop an iteration and move on to the next one immediately. The `continue` keyword accomplishes this:
```julia-repl
julia> for i = 1:10
           if i % 3 != 0
               continue
           end
           println(i)
       end
3
6
9
```
This is a somewhat contrived example since we could produce the same behavior more clearly by negating the condition and placing the `println` call inside the `if` block. In realistic usage there is more code to be evaluated after the `continue`, and often there are multiple points from which one calls `continue`.
Multiple nested `for` loops can be combined into a single outer loop, forming the cartesian product of its iterables:
```julia-repl
julia> for i = 1:2, j = 3:4
           println((i, j))
       end
(1, 3)
(1, 4)
(2, 3)
(2, 4)
```


## [Repeated Evaluation: Loops](#man-loops)
With this syntax, iterables may still refer to outer loop variables; e.g. `for i = 1:n, j = 1:i` is valid. However a `break` statement inside such a loop exits the entire nest of loops, not just the inner one. Both variables (`i` and `j`) are set to their current iteration values each time the inner loop runs. Therefore, assignments to `i` will not be visible to subsequent iterations:
```julia-repl
julia> for i = 1:2, j = 3:4
           println((i, j))
           i = 0
       end
(1, 3)
(1, 4)
(2, 3)
(2, 4)
```
If this example were rewritten to use a `for` keyword for each variable, then the output would be different: the second and fourth values would contain `0`.
Multiple containers can be iterated over at the same time in a single `for` loop using [`zip`](../../base/iterators/#Base.Iterators.zip):
```julia-repl
julia> for (j, k) in zip([1 2 3], [4 5 6 7])
           println((j,k))
       end
(1, 4)
(2, 5)
(3, 6)
```
Using [`zip`](../../base/iterators/#Base.Iterators.zip) will create an iterator that is a tuple containing the subiterators for the containers passed to it. The `zip` iterator will iterate over all subiterators in order, choosing the $i$th element of each subiterator in the $i$th iteration of the `for` loop. Once any of the subiterators run out, the `for` loop will stop.


## [Exception Handling](#Exception-Handling)
When an unexpected condition occurs, a function may be unable to return a reasonable value to its caller. In such cases, it may be best for the exceptional condition to either terminate the program while printing a diagnostic error message, or if the programmer has provided code to handle such exceptional circumstances then allow that code to take the appropriate action.


### [Built-in Exceptions](#Built-in-Exceptions)
`Exception`s are thrown when an unexpected condition has occurred. The built-in `Exception`s listed below all interrupt the normal flow of control.
| `Exception`                                                                |
|:---------------------------------------------------------------------------|
| [`ArgumentError`](../../base/base/#Core.ArgumentError)                     |
| [`BoundsError`](../../base/base/#Core.BoundsError)                         |
| [`CompositeException`](../../base/base/#Base.CompositeException)           |
| [`DimensionMismatch`](../../base/base/#Base.DimensionMismatch)             |
| [`DivideError`](../../base/base/#Core.DivideError)                         |
| [`DomainError`](../../base/base/#Core.DomainError)                         |
| [`EOFError`](../../base/base/#Base.EOFError)                               |
| [`ErrorException`](../../base/base/#Core.ErrorException)                   |
| [`InexactError`](../../base/base/#Core.InexactError)                       |
| [`InitError`](../../base/base/#Core.InitError)                             |
| [`InterruptException`](../../base/base/#Core.InterruptException)           |
| `InvalidStateException`                                                    |
| [`KeyError`](../../base/base/#Base.KeyError)                               |
| [`LoadError`](../../base/base/#Core.LoadError)                             |
| [`OutOfMemoryError`](../../base/base/#Core.OutOfMemoryError)               |
| [`ReadOnlyMemoryError`](../../base/base/#Core.ReadOnlyMemoryError)         |
| [`RemoteException`](../../stdlib/Distributed/#Distributed.RemoteException) |
| [`MethodError`](../../base/base/#Core.MethodError)                         |
| [`OverflowError`](../../base/base/#Core.OverflowError)                     |
| [`Meta.ParseError`](../../base/base/#Base.Meta.ParseError)                 |
| [`SystemError`](../../base/base/#Base.SystemError)                         |
| [`TypeError`](../../base/base/#Core.TypeError)                             |
| [`UndefRefError`](../../base/base/#Core.UndefRefError)                     |
| [`UndefVarError`](../../base/base/#Core.UndefVarError)                     |
| [`StringIndexError`](../../base/base/#Base.StringIndexError)               |