A world without extension functions
Imagine a scenario, you are coding a java android app, and you are using java.util.Calendar class for data and time management. You realize that you need to convert a calendar instance into a pretty format like “4 minutes ago…” but you are out of luck since Calendar object has no method that returns pretty format like that. The most common solution to this problem involves creating a util function that does that. Something like this:
So what is the main problem with this solution? It goes against OOP principles. Accessing CalendarUtils class directly all over the project tightly couples your code to this utils class, and that is not a good thing. It is impossible to switch later on to a different implementation of this class since its imported directly.
Another issue is testing, how can you test a class that directly imports a utils class? Tests written for this class will also test the utils class, and when you change that utils class, tests may break even if you did not touch your original class.
Object-oriented programming to save the day
A better way to solve this problem would be to use a wrapper around calendar object. Something like this:
Now, this is a much better implementation. We can create an interface around this class, provide multiple implementations, use dependency injection to provide this functionality to our app, a much better object-oriented solution.
What are downsides to this object-oriented implementation? It requires more code then the first solution, and it does almost the same thing. A whole class is created just to wrap a calendar object and provide one method on top of it.
A world with extension functions
For simple use cases, it would be nice to have some way of declaring functions that can be attached to some objects, and that function would have access to all properties of that object. So the effect would be similar to creating a wrapper class around that object, and we would not import that extension function all our code base, we would just call it upon the receiver object. It is still not a perfect solution but much better than creating utils classes.
Kotlin extension functions to the rescue! How would an extension function look like for the problem above?
The extension function is the second function in the snippet above, Calendar.minutesAgoFrom, and you can immediately recognize that in the name of the extension function we specify on which class we want to attach the method. In this case, it is the Calendar class. So every time we create a Calendar instance in our code minutesAgoFrom will be available on that Calendar instance. The second thing to notice is the use of this keyword inside the extension function. This is the main power of extension functions, it provides an access to all internals of the Calendar object, hence the use of this.timeInMillis.
Extension functions are a middle ground between a fully object-oriented solution and procedural coding with static utils classes.
To really appreciate the power of extension functions let’s look at the code below, taken from the Kotlin extension documentation.
How powerful is that? We just created an extension function that applies to all possible list types. Now every list in your app has a swap function that can swap elements no matter the list type.
This just scratches the beginning of what extension functions look like, in part 2 we will see some popular collections of extension functions and how they actually work behind the scenes.