1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
# Operators reference
This document is a complete reference of operators in Elixir, how they are parsed, how they can be defined, and how they can be overridden.
## Operator precedence and associativity
The following is a list of all operators that Elixir is capable of parsing, ordered from higher to lower precedence, alongside their associativity:
Operator | Associativity
---------------------------------------------- | -------------
`@` | Unary
`.` | Left
`+` `-` `!` `^` `not` | Unary
`**` | Left
`*` `/` | Left
`+` `-` | Left
`++` `--` `+++` `---` `..` `<>` | Right
`in` `not in` | Left
`\|>` `<<<` `>>>` `<<~` `~>>` `<~` `~>` `<~>` | Left
`<` `>` `<=` `>=` | Left
`==` `!=` `=~` `===` `!==` | Left
`&&` `&&&` `and` | Left
`\|\|` `\|\|\|` `or` | Left
`=` | Right
`&`, `...` | Unary
`=>` (valid only inside `%{}`) | Right
`\|` | Right
`::` | Right
`when` | Right
`<-` `\\` | Left
## General operators
Elixir provides the following built-in operators:
* [`+`](`+/1`) and [`-`](`-/1`) - unary positive/negative
* [`+`](`+/2`), [`-`](`-/2`), [`*`](`*/2`), and [`/`](`//2`) - basic arithmetic operations
* [`++`](`++/2`) and [`--`](`--/2`) - list concatenation and subtraction
* [`and`](`and/2`) and [`&&`](`&&/2`) - strict and relaxed boolean "and"
* [`or`](`or/2`) and [`||`](`||/2`) - strict and relaxed boolean "or"
* [`not`](`not/1`) and [`!`](`!/1`) - strict and relaxed boolean "not"
* [`in`](`in/2`) and [`not in`](`in/2`) - membership
* [`@`](`@/1`) - module attribute
* [`..`](`../0`), [`..`](`../2`), and [`..//`](`..///3`) - range creation
* [`<>`](`<>/2`) - binary concatenation
* [`|>`](`|>/2`) - pipeline
* [`=~`](`=~/2`) - text-based match
Many of those can be used in guards; consult the [list of allowed guard functions and operators](patterns-and-guards.md#list-of-allowed-functions-and-operators).
Additionally, there are a few other operators that Elixir parses but doesn't actually use.
See [Custom and overridden operators](#custom-and-overridden-operators) below for a list and for guidelines about their use.
Some other operators are special forms and cannot be overridden:
* [`^`](`^/1`) - pin operator
* [`.`](`./2`) - dot operator
* [`=`](`=/2`) - match operator
* [`&`](`&/1`) - capture operator
* [`::`](`::/2`) - type operator
Finally, these operators appear in the precedence table above but are only meaningful within certain constructs:
* `=>` - see [`%{}`](`%{}/1`)
* `when` - see [Guards](patterns-and-guards.md#guards)
* `<-` - see [`for`](`for/1`) and [`with`](`with/1`)
* `\\` - see [Default arguments](`Kernel#def/2-default-arguments`)
## Comparison operators
Elixir provides the following built-in comparison operators (all of which can be used in guards):
* [`==`](`==/2`) - equal to
* [`===`](`===/2`) - strictly equal to
* [`!=`](`!=/2`) - not equal to
* [`!==`](`!==/2`) - strictly not equal to
* [`<`](`</2`) - less-than
* [`>`](`>/2`) - greater-than
* [`<=`](`<=/2`) - less-than or equal to
* [`>=`](`>=/2`) - greater-than or equal to
The only difference between [`==`](`==/2`) and [`===`](`===/2`) is that [`===`](`===/2`) is strict when it comes to comparing integers and floats:
```elixir
iex> 1 == 1.0
true
iex> 1 === 1.0
false
```
[`!=`](`!=/2`) and [`!==`](`!==/2`) act as the negation of [`==`](`==/2`) and [`===`](`===/2`), respectively.
## Custom and overridden operators
### Defining custom operators
Elixir is capable of parsing a predefined set of operators. It's not possible to define new operators (as supported by some languages). However, not all operators that Elixir can parse are *used* by Elixir: for example, `+` and `||` are used by Elixir for addition and boolean *or*, but `<~>` is not used (but valid).
To define an operator, you can use the usual `def*` constructs (`def`, `defp`, `defmacro`, and so on) but with a syntax similar to how the operator is used:
```elixir
defmodule MyOperators do
# We define ~> to return the maximum of the given two numbers,
# and <~ to return the minimum.
def a ~> b, do: max(a, b)
def a <~ b, do: min(a, b)
end
```
To use the newly defined operators, you **have to** import the module that defines them:
```elixir
iex> import MyOperators
iex> 1 ~> 2
2
iex> 1 <~ 2
1
```
The following is a table of all the operators that Elixir is capable of parsing, but that are not used by default:
* `|||`
* `&&&`
* `<<<`
* `>>>`
* `<<~`
* `~>>`
* `<~`
* `~>`
* `<~>`
* `+++`
* `---`
* `...`
The following operators are used by the `Bitwise` module when imported: [`&&&`](`Bitwise.&&&/2`), [`<<<`](`Bitwise.<<</2`), [`>>>`](`Bitwise.>>>/2`), and [`|||`](`Bitwise.|||/2`). See the `Bitwise` documentation for more information.
Note that the Elixir community generally discourages custom operators. They can be hard to read and even more to understand, as they don't have a descriptive name like functions do. That said, some specific cases or custom domain specific languages (DSLs) may justify these practices.
It is also possible to replace predefined operators, such as `+`, but doing so is extremely discouraged.
|