"Fossies" - the Fresh Open Source Software Archive

Member "kotlin-1.3.61/spec-docs/operator-conventions.md" (26 Nov 2019, 5888 Bytes) of package /linux/misc/kotlin-1.3.61.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format (assuming markdown format). Alternatively you can here view or download the uninterpreted source code file. A member file download can also be achieved by clicking within a package contents listing on the according byte size field.

Operator Conventions

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 (see grammar). To implement an operator, we provide a member function or an extension function with a fixed name, for the corresponding type, i.e. left-hand side type for binary operations and argument type for unary ones.

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

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:

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.

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++:

The effect of computing the expression is:

For a-- the steps are completely analogous.

For the prefix forms ++a and --a resolution works the same way, and the effect is:

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)

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

{:#Equals}

Expression Translated to
a == b a?.equals(b) ?: b === null
a != b !(a?.equals(b) ?: b === null)

Note: === and !== (identity checks) are not overloadable, so no conventions exist for them

The == operation is special in two ways:

fun equals(other: Any?): Boolean

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.

Indexing and invocations

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.

Symbol Translated to
a(i) a.invoke(i)
a(i, j) a.invoke(i, j)
a(i_1, ..., i_n) a.invoke(i_1, ..., i_n)

Parentheses are translated to calls to invoke with appropriate number of arguments.

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:

Note: assignments are NOT expressions in Kotlin.

Discussion of the ambiguity rule: We raise an error when both plus() and plusAssign() are available only if the lhs is assignable. Otherwise, the availability of plus() is irrelevant, because we know that a = a + b can not compile. An important concern here is what happens when the lhs becomes assignable after the fact (e.g. the user changes val to var or provides a set() function for indexing convention): in this case, the previously correct call site may become incorrect, but not the other way around, which is safe, because former calls to plusAssign() can not be silently turned into calls to plus().