[Kotlin] allows us to provide implementations for a predefined set of operators on our types. These operators have fixed symbolic representation (like '{{+}}' or '{{*}}') and fixed [precedence|Grammar#Precedence]. To implement an operator, one provides a [member function|Functions#Member functions] or an [extension function|Extension functions] with a fixed name, for the corresponding type, i.e. left-hand side type for binary operations and argument type for unary ones. 

h3. Conventions

Here we describe the conventions that regulate operator overloading for different operators.

h5. Unary operations

||Expression||Translated to||
| {{+a}}      | {{a.plus()}} |
| {{-a}}      | {{a.minus()}} |
| {{!a}}      | {{a.not()}} |

This table says that when the compiler processes, for example, an expression {{+a}}, it performs the following steps:
# Determines the type of {{a}}, let it be {{T}}.
# Looks up a function {{plus()}} with no parameters for the receiver {{T}}, i.e. a member function or an extension function.
# If the function is absent or ambiguous, it is a compilation error.
# If the function is present and its return type is {{R}}, the expression {{+a}} has type {{R}}.

*Note* that these operations, as well as all the others, are optimized for [Basic types] and do not introduce overhead of function calls for them.

||Expression||Translated to||
| {{a++}}   | {{a.inc()}} + see below |
| {{a--}}   | {{a.dec()}} + see below |

These operations are supposed to change their receiver and (optionally) return a value. 
{note:title=inc()/dec() shouldn't mutate the receiver object}
By "changing the receiver" we mean the receiver-variable, not the receiver object.
{note}
The compiler performs the following steps for resolution of an operator in the *postfix* form, e.g. {{a++}}:
# Determines the type of {{a}}, let it be {{T}}.
# Looks up a function {{inc()}} with no parameters, applicable to the receiver of type {{T}}.
# If the function returns a type {{R}}, then it must be a subtype of {{T}}.

The effect of computing the expression is:
# Store the initial value of {{a}} to a temporary storage {{a0}},
# Assign the result of {{a.inc()}} to {{a}},
# Return {{a0}} as a result of the expression.

For {{a--}} the steps are completely analogous. 

For the *prefix* forms {{++a}} and {{--a}} resolution works the same way, and the effect is:
# Assign the result of {{a.inc()}} to {{a}},
# Return the new value of {{a}} as a result of the expression.

h5. Binary operations

||Expression||Translated to||
| {{a + b}} | {{a.plus(b)}} |
| {{a - b}} | {{a.minus(b)}} |
| {{a * b}} | {{a.times(b)}} |
| {{a / b}} | {{a.div(b)}} |
| {{a % b}} | {{a.mod(b)}} |
| {{a..b}}  | {{a.rangeTo(b)}} |

For the operations in this table, the compiler just resolves the expression in the *Translated to* column.

||Expression||Translated to||
| {{a in b}} | {{b.contains(a)}} |
| {{a !in b}} | {{!b.contains(a)}} |

{anchor:in}
For *in* and *!in* the procedure is the same, but the order of arguments is reversed.

||Symbol||Translated to||
| {{a\[i\]}}  | {{a.get\(i\)}} |
| {{a\[i, j\]}}  | {{a.get\(i, j\)}} |
| {{a\[i_1, ...,  i_n\]}}  | {{a.get\(i_1, ...,  i_n\)}} |
| {{a\[i\] = b}} | {{a.set(i, b)}} |
| {{a\[i, j\] = b}} | {{a.set(i, j, b)}} |
| {{a\[i_1, ...,  i_n\] = b}} | {{a.set(i_1, ..., i_n, b)}} |

Square brackets are translated to calls to {{get}} and {{set}} with appropriate numbers of arguments.

{anchor:assignments}
||Expression||Translated to||
| {{a += b}} | {{a.plusAssign(b)}} |
| {{a -= b}} | {{a.minusAssign(b)}} |
| {{a *= b}} | {{a.timesAssign(b)}} |
| {{a /= b}} | {{a.divAssign(b)}} |
| {{a %= b}} | {{a.modAssign(b)}} |

For the assignment operations, e.g. {{a += b}}, the compiler performs the following steps:
# If the function from the right column is available
## If the corresponding binary function (i.e. {{plus()}} for {{plusAssign()}}) is available too, report error (ambiguity).
## Make sure its return type is {{Unit}}, and report an error otherwise.
## Generate code for {{a.plusAssign(b)}}
# Otherwise, try to generate code for {{a = a + b}} (this includes a type check: the type of {{a + b}} must be a subtype of {{a}}).

*Note*: assignments are *NOT* expressions in [Kotlin].

{anchor:Equals}
||Expression||Translated to||
| {{a == b}} | {{a?.equals(b) ?: b.identityEquals(null)}} |
| {{a \!= b}} | {{\!(a?.equals(b) ?: b.identityEquals(null))}} |

*Note*: {{identityEquals}} checks if two references point to the same object.

The {{==}} operation is special in two ways:
# It is translated to a complex expression that screens for *null*'s, and {{null == null}} is *true*.
# It looks up a function with a specific _signature_, not just a specific _name_. The function must be declared as
{code}
fun equals(other : Any?) : Boolean
{code}
Or an extension function with the same parameter list and return type.

||Symbol||Translated to||
| {{a > b}}  | {{a.compareTo(b) > 0}} |
| {{a < b}}  | {{a.compareTo(b) < 0}} |
| {{a >= b}} | {{a.compareTo(b) >= 0}} |
| {{a <= b}} | {{a.compareTo(b) <= 0}} |

All comparisons are translated into calls to {{compareTo}}, that is required to return {{Int}}.

h4. Infix calls for named functions

One can simulate custom infix operations by using [infix function calls|Functions#Infix calls].

h3. What's next

* [Extension functions]
* [Function literals]
* [Type-safe Groovy-style builders]