0
0
Kotlinprogramming~15 mins

Why operators are functions in Kotlin - Why It Works This Way

Choose your learning style9 modes available
Overview - Why operators are functions in Kotlin
What is it?
In Kotlin, operators like +, -, *, and / are actually special functions. This means when you write a + b, Kotlin is calling a function named plus on a. This design lets you customize how operators work for your own types by defining these functions yourself. So, operators are just a simpler way to call functions.
Why it matters
This approach makes Kotlin very flexible and consistent. Without operators as functions, you would need different rules for operators and functions, making the language harder to learn and use. It also allows you to create clear, readable code that behaves exactly how you want, especially when working with your own data types.
Where it fits
Before this, you should understand basic Kotlin functions and classes. After this, you can learn about operator overloading and how to define your own operator functions to make custom types work naturally with operators.
Mental Model
Core Idea
Operators in Kotlin are just special function calls that can be customized like any other function.
Think of it like...
Think of operators as remote controls for functions. Pressing a button (like +) sends a signal to a function that does the work behind the scenes.
Expression: a + b
↓
Function call: a.plus(b)

┌─────────┐      ┌────────────┐
│  a + b  │  →   │ a.plus(b)  │
└─────────┘      └────────────┘
Build-Up - 6 Steps
1
FoundationUnderstanding basic functions in Kotlin
🤔
Concept: Functions are blocks of code that perform tasks and can be called with inputs.
In Kotlin, you define a function with fun keyword. For example: fun add(x: Int, y: Int): Int { return x + y } You call it like add(2, 3) which returns 5.
Result
You get a reusable piece of code that adds two numbers.
Knowing how functions work is essential because operators in Kotlin are just special functions.
2
FoundationWhat are operators in programming?
🤔
Concept: Operators are symbols like + or * that perform common tasks like addition or multiplication.
When you write 2 + 3, the + operator adds the two numbers. Operators make code shorter and easier to read compared to calling functions directly.
Result
You can write expressions like 2 + 3 instead of add(2, 3).
Operators are a shorthand for common operations, making code cleaner and more natural.
3
IntermediateOperators as functions in Kotlin
🤔Before reading on: do you think operators like + are separate from functions or actually functions themselves? Commit to your answer.
Concept: In Kotlin, operators are actually functions with special names like plus, minus, times, etc.
For example, a + b is the same as a.plus(b). Kotlin lets you call operators as functions and vice versa. This means operators are not magic but normal functions with a special syntax.
Result
You can use either operator syntax or function call syntax interchangeably.
Understanding operators as functions reveals Kotlin's consistent design and lets you customize operator behavior.
4
IntermediateOperator overloading by defining functions
🤔Before reading on: can you guess how Kotlin lets you change what + does for your own classes? Commit to your answer.
Concept: You can define functions like plus inside your classes to change how operators work with your objects.
Example: class Point(val x: Int, val y: Int) { operator fun plus(other: Point) = Point(x + other.x, y + other.y) } Now, Point(1,2) + Point(3,4) calls the plus function you defined.
Result
Operators work naturally with your custom types, making code readable and expressive.
Knowing operator overloading lets you write intuitive code that fits your domain perfectly.
5
AdvancedBenefits of operators as functions for language design
🤔Before reading on: do you think making operators functions helps or complicates language consistency? Commit to your answer.
Concept: Treating operators as functions unifies syntax and semantics, simplifying the language and compiler design.
Because operators are functions, Kotlin can reuse function call mechanisms for operators. This reduces special cases and bugs. It also allows extension functions to add operator support to existing types without changing their code.
Result
Kotlin is easier to maintain and extend, and developers get powerful tools for customization.
Understanding this design choice shows how language simplicity and power can go hand in hand.
6
ExpertHow Kotlin resolves operator calls at runtime
🤔Before reading on: do you think operator calls are handled differently at runtime than normal function calls? Commit to your answer.
Concept: At runtime, operator calls are just normal function calls resolved by the Kotlin compiler and JVM.
When you write a + b, Kotlin compiles it to a call to a.plus(b). The JVM sees no difference between this and any other function call. This means operator calls have no extra runtime cost or special handling.
Result
Operator usage is efficient and consistent with normal function calls.
Knowing this prevents misconceptions about performance or behavior differences between operators and functions.
Under the Hood
Kotlin treats operators as functions with specific names like plus, minus, times, etc. When the compiler sees an operator, it translates it into a function call to the corresponding function on the left operand. If the function is defined with the operator keyword, it can be called using operator syntax. At runtime, these are just normal function calls handled by the JVM with no special operator instructions.
Why designed this way?
This design unifies the language syntax and semantics, reducing complexity. Instead of having separate rules for operators and functions, Kotlin uses one mechanism. It also enables powerful features like operator overloading and extension functions. Other languages either treat operators as special syntax or functions, but Kotlin chose functions for consistency and flexibility.
┌───────────────┐
│  Source Code  │
│  a + b       │
└──────┬────────┘
       │ compiled to
       ▼
┌───────────────┐
│ Function Call │
│ a.plus(b)     │
└──────┬────────┘
       │ runtime call
       ▼
┌───────────────┐
│ JVM executes  │
│ plus function │
└───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Do you think operators in Kotlin are completely separate from functions? Commit yes or no.
Common Belief:Operators are special language features unrelated to functions.
Tap to reveal reality
Reality:Operators are actually functions with special names and can be called like any other function.
Why it matters:Believing operators are separate can confuse learners and prevent them from understanding operator overloading and extension functions.
Quick: Do you think operator overloading can change the meaning of operators for built-in types like Int? Commit yes or no.
Common Belief:You can redefine operators for built-in types like Int to do anything you want.
Tap to reveal reality
Reality:You cannot change operators for built-in types; you can only overload them for your own classes.
Why it matters:Trying to change built-in operator behavior leads to errors and confusion about language capabilities.
Quick: Do you think operator functions add extra runtime cost compared to normal functions? Commit yes or no.
Common Belief:Operators are special and slower or faster than normal functions at runtime.
Tap to reveal reality
Reality:Operator calls compile down to normal function calls with no extra runtime cost.
Why it matters:Misunderstanding this can lead to wrong performance assumptions and premature optimization.
Quick: Do you think all operators in Kotlin can be overloaded? Commit yes or no.
Common Belief:Every operator symbol in Kotlin can be overloaded by defining a function.
Tap to reveal reality
Reality:Only a specific set of operators can be overloaded; some operators are fixed and cannot be changed.
Why it matters:Expecting to overload unsupported operators causes frustration and wasted effort.
Expert Zone
1
Operator functions must be marked with the operator keyword to enable operator syntax usage.
2
Extension functions can add operator support to classes you do not own, increasing flexibility.
3
Kotlin's operator functions follow naming conventions that map operators to function names, which must be exact.
When NOT to use
Avoid operator overloading when it makes code confusing or breaks expected behavior. Use regular functions when the operation is not naturally an operator or when clarity is more important than brevity.
Production Patterns
In production, operator overloading is used for math libraries, vector and matrix classes, DSLs, and domain-specific types to make code concise and expressive. Teams often document operator behavior to avoid misuse.
Connections
Function Overloading
Operator overloading is a special case of function overloading with fixed function names.
Understanding function overloading helps grasp how Kotlin allows multiple functions with the same name but different parameters, including operators.
Polymorphism in Object-Oriented Programming
Operator functions enable polymorphic behavior by letting different classes define their own operator implementations.
Knowing polymorphism clarifies how the same operator symbol can do different things depending on the object type.
Mathematical Notation
Operators in Kotlin mirror mathematical symbols, making code resemble math expressions.
Recognizing this connection helps learners appreciate why operator syntax improves code readability and expressiveness.
Common Pitfalls
#1Defining operator functions without the operator keyword.
Wrong approach:class Point(val x: Int, val y: Int) { fun plus(other: Point) = Point(x + other.x, y + other.y) } val p1 = Point(1,2) val p2 = Point(3,4) val p3 = p1 + p2 // Error: Operator '+' cannot be applied
Correct approach:class Point(val x: Int, val y: Int) { operator fun plus(other: Point) = Point(x + other.x, y + other.y) } val p1 = Point(1,2) val p2 = Point(3,4) val p3 = p1 + p2 // Works correctly
Root cause:For Kotlin to recognize a function as an operator, it must be marked with the operator keyword.
#2Trying to overload operators for built-in types like Int.
Wrong approach:operator fun Int.plus(other: Int): Int = this - other // Trying to change + to - for Int val result = 5 + 3 // Still 8, not 2
Correct approach:// Cannot overload operators for built-in types; use custom types instead class MyInt(val value: Int) { operator fun plus(other: MyInt) = MyInt(value - other.value) } val a = MyInt(5) val b = MyInt(3) val c = a + b // Uses custom plus
Root cause:Kotlin does not allow changing operator behavior for built-in types to keep language consistency and safety.
#3Overloading operators in ways that confuse readers.
Wrong approach:class Strange { operator fun plus(other: Strange) = this // plus returns this without change } // Using + operator but it does not behave like addition
Correct approach:class Strange { operator fun plus(other: Strange) = Strange() // plus returns a new meaningful object } // Operator behavior matches user expectations
Root cause:Misusing operator overloading breaks code readability and can cause bugs.
Key Takeaways
In Kotlin, operators are just special functions with fixed names and syntax.
This design makes the language consistent, flexible, and easy to extend with custom types.
Operator overloading lets you define how operators work for your own classes, improving code clarity.
At runtime, operator calls are normal function calls with no extra cost or special handling.
Using operator functions correctly requires the operator keyword and following naming conventions.