Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The + operator in Kotlin is a statically resolved, overloadable operator primarily functioning as a binary addition/concatenation operator or a unary positive operator. Rather than being a hardcoded language construct limited to primitives, the Kotlin compiler translates the + symbol into explicit method calls to functions named plus (for binary operations) or unaryPlus (for unary operations).

Compiler Translation Mechanics

When the Kotlin compiler encounters the + operator, it performs a desugaring process based on the arity of the operation. Binary Operation (a + b) The compiler translates the infix + operator into a call to the plus() function invoked on the left-hand operand, passing the right-hand operand as the argument.
val result = a + b
// Compiles down to:
val result = a.plus(b)
Unary Operation (+a) When used as a prefix, the compiler translates the + operator into a call to the unaryPlus() function invoked on the operand.
val result = +a
// Compiles down to:
val result = a.unaryPlus()

Type-Specific Implementations

Because + relies on function resolution, its behavior is strictly dictated by the type of the left-hand operand:
  • Primitives: For numeric types (Int, Double, etc.), Kotlin maps the plus and unaryPlus functions directly to the corresponding JVM bytecode instructions (e.g., iadd, dadd) to ensure zero runtime overhead.
  • Strings: When the left operand is a String, plus(Any?) is invoked. On the JVM, Kotlin optimizes this during compilation using StringBuilder or StringConcatFactory (depending on the target JVM version) rather than executing literal method calls.
  • Collections: The Kotlin standard library provides extension functions for Iterable.plus and Collection.plus. Mechanically, this operator does not mutate the existing collection; it allocates and returns a new read-only collection containing the elements of the original collection followed by the appended element(s).

Operator Overloading Syntax

To enable the + operator for custom types, you must declare a member or extension function using the operator modifier. The function must be named exactly plus or unaryPlus.
class Matrix(val data: List<Int>) {
    // Overloading the binary '+' operator
    operator fun plus(other: Matrix): Matrix {
        require(this.data.size == other.data.size)
        return Matrix(this.data.zip(other.data) { a, b -> a + b })
    }

    // Overloading the unary '+' operator
    operator fun unaryPlus(): Matrix {
        return Matrix(this.data.map { +it })
    }
}

Resolution Rules and Constraints

  1. Asymmetry: The plus function does not require the parameter type to match the receiver type. a + b is valid as long as a has a plus function accepting the type of b.
  2. Return Type: The return type of the plus or unaryPlus function dictates the type of the resulting expression. It is not constrained to return the same type as the operands.
  3. Precedence: The binary + operator shares the same precedence level as the binary - operator, which is lower than multiplicative operators (*, /, %) but higher than infix functions and comparison operators. Unary + has a higher precedence than all binary arithmetic operators.
  4. Nullability: The + operator can be invoked where the left operand is a nullable variable (written simply as a + b where a is of type T?) only if an explicit extension function for the nullable type is defined and resolved (e.g., operator fun Point?.plus(other: Point): Point). Without such an extension, the compiler enforces null safety and rejects the operation.
Master Kotlin with Deep Grasping Methodology!Learn More