6 minutes read

Kotlin is a language that adapts to your way of programming or code writing, which allows you to develop the code you want when you want. Kotlin offers mechanisms that help us create code that is easy to read and understand.

One of the most interesting mechanisms is the infix notation. It allows us to define and use functions without parentheses or dots.

Infix notation

The infix notation is used in arithmetical and logical code. It is characterized by the placement of operators between operands: for example, 2 + 3, where "+" is the infix operator.

In infix notation, the function name is placed between the arguments and the name of the function itself is the operator. An example of such a function would be add(2, 4) in which the function add denotes addition ("add"): add(2, 4) = 2 add 4.

To define an infix function, you must meet the following requirements.

  • They must be member functions or extension functions.
  • They must have a single parameter.
  • The parameter must not accept variable number of arguments and must have no default value.

To define your own functions with the infix notation, just add the infix keyword to your function definition.

infix fun Int.add(x: Int): Int = this + x

fun main() {
    println(1.add(2)) // result is 3 as extension function
    println(1 add 2)  // result is 3 as infix function
}

Creating infix functions

You can create infix functions whenever you want: for example, to improve the readability of your code or create a DSL (Domain Specific Language). But remember, infix function calls have lower precedence than arithmetic operators or other elements defined in the language, like type casts and the rangeTo operator.

infix fun Int.add(x: Int): Int = this + x
fun main() {
    println(1 add 2 + 3)   // 6
    println(1 add (2 + 3)) // 6
    println(0..(1 add 3))  // 0..4
}

On the other hand, an infix function's call precedence is higher than that of the boolean operators && and ||, is- and in-checks, and some other operators.

infix fun Int.add(x: Int): Int = this + x
fun main() {
    println(1 and 2 xor 3 add 4) // 1 and 2 xor (3 add 4) -> 7
    println(1 add 2 in 3..4)     // (1 add 2) in 3..4 -> true
}

Remember also that infix functions always require both the receiver and the parameter to be specified and that you must use this to reference the current receiver.

infix fun Int.add(x: Int): Int = this + x // this is the receiver
fun main() {
    println(2 + 3) // receiver is 2
}

Standard Library Infix Functions

In the Kotlin standard library, we have many examples of functions used with the infix notation:

  • Function to(): with Pair<A, B> and Map<T, V>.
  • Bitwise functions: and(), or(), shl(), shr(), ushr(), and xor().
  • Boolean class methods: and(), or(), and xor().
  • String class methods: match and zip functions.
fun main() {
    println("Hi" to "Kotlin")                          // ("Hi", "Kotlin")
    println(0x123456 shr 16)                           // 18
    println(true and false or true xor false)          // true
    println("Hi, Kotlin" matches ".*Kotlin".toRegex()) // true
}

Conclusion

Infix functions are a powerful tool for making our code more readable and maintainable. Using them, you must take into account the indicated requirements as well as the order of precedence of operators. Infix notation will help you take your code to another level of quality and expand the possibilities of code writing.

Now is the time to do some tasks to check what you have learned. Are you ready?

58 learners liked this piece of theory. 3 didn't like it. What about you?
Report a typo