Infix Functions in Kotlin
Bringing our code closer to natural language
Imagine you have the following model to represent a Poker Card:
enum class Suit {
HEARTS,
SPADES,
CLUBS,
DIAMONDS
}enum class Rank {
TWO, THREE, FOUR, FIVE,
SIX, SEVEN, EIGHT, NINE,
TEN, JACK, QUEEN, KING, ACE
}data class Card(val rank: Rank, val suit: Suit)
It is a very easy model, basically it has three parts:
- Suit. The card suit (hearts, spades clubs or diamonds).
- Rank. The card value (five, jack, king, etc.).
- Card. A class compounded by rank and suit.
In order to create a card we have to do the following:
val card = Card(Rank.QUEEN, Suit.HEARTS)
The idea is to simplify the way of creating a new card so we’re going to add a function called of
to Rank
:
enum class Rank {
TWO, THREE, FOUR, FIVE,
SIX, SEVEN, EIGHT, NINE,
TEN, JACK, QUEEN, KING, ACE; fun of(suit: Suit) = Card(this, suit)
}
What is of
? It builds a new card from a Suit
passed as argument and the Rank
itself. What do we get? Add some semantic to the card creation:
val card = Rank.QUEEN.of(Suit.HEARTS)
We can still improve it if we use static imports for QUEEN
and HEARTS
to get the card creation closer to natural language:
val card = QUEEN.of(HEARTS)
Much better, right?. But there’re still more, let’s convert the of
function in an infix function. We only have to add the reserved word infix
at the beginning of the function:
enum class Rank {
TWO, THREE, FOUR, FIVE,
SIX, SEVEN, EIGHT, NINE,
TEN, JACK, QUEEN, KING, ACE;
infix fun of(suit: Suit) = Card(this, suit)
}
What is an infix function
? Add to the function the ability to use it with infix notation, that means we can use the function as an arithmetic operator, i.e., using it without writing dots and parentheses.
val card = QUEEN of HEARTS
We could say it is syntactic sugar but it also help us to get our code closer to language natural doing it much more readable and lean.
This post is also available in Spanish here: https://arturogutierrez.com/blog/infix-functions-en-kotlin/