This page looks best with JavaScript enabled

Kotlin Infix functions

 ·  ☕ 4 min read  ·  ✍️ Ignacio Carrión

Exploring Kotlin Infix Functions: A Deep Dive

Kotlin, as a modern programming language, is packed with features that make code expressive and concise. One of these features is infix functions, which allow you to write cleaner and more readable code. In this blog post, we’ll explore what infix functions are, how to use them, and some practical use cases.


What Are Infix Functions?

Infix functions in Kotlin are a special kind of function that can be called without using parentheses or the dot operator. This can make certain code patterns more natural and readable, resembling traditional mathematical or DSL (Domain Specific Language) syntax.

Here’s an example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class Point(val x: Int, val y: Int) {
    infix fun moveBy(offset: Point): Point {
        return Point(this.x + offset.x, this.y + offset.y)
    }
}

fun main() {
    val point1 = Point(2, 3)
    val offset = Point(1, 1)

    // Using the infix notation
    val newPoint = point1 moveBy offset

    println("New Point: (\${newPoint.x}, \${newPoint.y})")
}

In this example, the moveBy function is called using infix notation, improving readability.


Rules and Syntax

Here are a few key points about infix functions:

  • Single Parameter: The function must take exactly one parameter.
  • Class Member or Extension Function: It must be defined as a member function or an extension function.
  • No Varargs or Default Arguments: The parameter cannot have default values or be a vararg.

Example of an extension function:

1
2
3
4
5
6
7
8
infix fun String.concatWith(other: String): String {
    return this + other
}

fun main() {
    val result = "Hello" concatWith " World"
    println(result)  // Outputs: Hello World
}

Practical Use Cases

Infix functions are commonly used in Kotlin to make code more concise and readable. They shine in scenarios where intuitive operations are necessary, such as working with collections, ranges, or creating expressive testing frameworks. Below are some examples of how infix functions can simplify everyday coding tasks:

  1. Mapping Keys to Values: The to function in Kotlin’s standard library is an infix function that helps in creating pairs, often used in maps.

    1
    2
    3
    4
    
    fun main() {
        val map = mapOf("key1" to "value1", "key2" to 42)
        println(map)  // Outputs: {key1=value1, key2=42}
    }
    
  2. Defining Ranges: The until function is an infix function used to define ranges that exclude the upper bound.

    1
    2
    3
    4
    5
    
    fun main() {
        for (i in 1 until 5) {
            println(i)  // Outputs: 1, 2, 3, 4
        }
    }
    
  3. Mocking in Tests: Libraries like MockK use infix functions to create expressive and readable test setups.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    
    class Calculator {
        fun add(a: Int, b: Int): Int = a + b
    }
    
    fun test() {
        val calculator = mockk<Calculator>()
        every { calculator.add(1, 2) } returns 3
    
        println(calculator.add(1, 2))  // Outputs: 3
    }
    
  4. Dependency Injection with Koin: Koin, a dependency injection framework for Kotlin, uses the bind infix function to define bindings in a clean and readable way.

    1
    2
    3
    4
    5
    6
    
    interface MyInterface
    class MyImplementation : MyInterface
    
    val appModule = module {
        single { MyImplementation() } bind MyInterface::class
    }
    

    The bind infix function enhances readability when declaring that a specific implementation should be used for an interface.


When to Use Infix Functions

While infix functions can make code cleaner, they should be used judiciously. Use them when:

  • The operation is intuitive and widely understood.
  • They enhance readability and flow.
  • They fit naturally into a DSL.

Avoid using infix functions when:

  • It could lead to ambiguous or confusing syntax.
  • The function’s purpose isn’t clear from its name or usage.

Conclusion

Kotlin’s infix functions are a powerful tool for creating expressive and readable code. Whether you’re defining a DSL, simplifying mathematical operations, or enhancing logical expressions, infix functions can make your code more elegant. However, as with any feature, they should be used thoughtfully to maintain code clarity and avoid overcomplication.

Try incorporating infix functions in your next Kotlin project and see how they transform your code! What are your favorite infix functions or creative ways to use them? Share your experiences in the comments!

Share on

Ignacio Carrión
WRITTEN BY
Ignacio Carrión
Android Developer