Me, trying to convince Android team to use Kotlin
Nearly 2 years ago our team decided to try something new: develop a commercial application entirely in Kotlin, a programming language by JetBrains. At that time, we had experience with Kotlin but on a much smaller scale: converting some parts of apps to a new language or trying it on pet projects. However, developing a commercial application in a new programming language introduces some difficulties:
All that may lead to missed delivery dates and stability issues of the application.
One should have strong incentives to make the transition. Our incentive was the belief that Kotlin would be the game changer for the Android Platform development. And that it’s Fun.
Keeping the Kotlin reference open, we started to develop the Voter application. Kotlin is a JVM language with 100% Java interoperability, and if you’re familiar with Java, learning Kotlin is easy. However, if you want to fully take advantage of the language, understanding functional programming concepts is essential.
Learning Functional Programming takes a while. So be patient.
And Functional Programming is not easy. At least in the beginning. Until it becomes fun. I strongly advise to take a set of courses by Martin Ordersky “Functional Programming in Scala”. Scala can be overwhelming at times, but it gives a great overview of the new functional programming mindset. You can treat Kotlin as a simpler version of Scala.
Kotlin is 100% interoperable with Java. Also, Kotlin is a functional language. And the latter allows writing more elegant, expressive code.
The concept of a pure function (a function that does not have side effects) is the most important functional concept which allowed us to greatly reduce code complexity and get rid of most mutable states.
In Imperative Programming Languages such as Javascript, Java, and C#, Side Effects are everywhere. This makes debugging very difficult because a variable can be changed anywhere in your program. So when you have a bug because a variable is changed to the wrong value at the wrong time, where do you look? Everywhere? That’s not good.
Note that how we manipulate data without changing its content.
2. Higher-order functions
Higher-order Functions either take functions as parameters, return functions or both.
Higher-order functions are everywhere. You just pass functions to collections to make code easy to read. titles.map { it.toUpperCase()}
reads like plain English. Isn’t it wonderful?
Let’s imagine a situation where we want to count the number of unread messages of different types. A typical approach would be:
As you can see, as new requirements are introduced, the code becomes unreadable and unmanageable. Let’s see how we can solve this problem with higher-order functions:
And we can imagine use cases where we would want to parametrize the fold
function argument, let’s say, for calculating the product of unread messages.
Another example of using higher-order functions is replacing numerous Listeners with simple higher-order function:
BillingView : LinearLayout {
var billingChangeListener: (() -> Unit)? = null...
}
... // in an activity far, far awaybillingView.billingChangeListener { updateUI() }
**3. Immutability**Immutability makes it easier to write, use and reason about the code (class invariant is established once and then unchanged). The internal state of your app components will be more consistent. Kotlin enforces immutability by introducing val
keyword as well as Kotlin collections, which are immutable by default. Once the val
or a collection is initialized, you can be sure about its validity. (See UPD for more accurate definition on val
keyword).
data class Address(val line1: String, val city: String)
val items = listOf(Address("242 5th St", "Los Angeles"), Address("Dovzhenka St. 5", "Kiev"))
This language feature made us think carefully about nullability of fields in our model classes. Previously, you were not sure whether field in DTO is initialized or not, @Nullable and @NotNull annotations helped, but not as much. Now, with Kotlin, you precisely know what field can be null, what field is are initialized later (e.g. fields injected by Dagger) and you get strict control over those fields. Result? Almost no NullPointerExceptions
. (Internally we call ?.
a “goose” operator, because it looks like a goose’s neck)
brand?.let { badge.enabled = brand.isNewBadge }// Can also be written asbadge.enabled = brand?.isNewBadge?:false
Anko DSL is a great library which significantly simplifies working with views, threads, and android lifecycle. The Github description states that Anko is “Pleasant Android application development” and it truly proved to be so.
Note that when uiThread
is called inside Activity, the block will not execute if isFinishing
is true
. We do not actually use this feature, as RxJava handles all the threading in our apps, but it is a nice feature.
Using Anko instead of XML. Although Anko is not ready to replace standard Android UI building, sometimes it is very handy.
As you can see, Anko DSL allows you to use custom views alongside Android built-in views. This is where it has a great advantage over standard XML.
Bored yet? I bet you scrolled that without reading. In Kotlin, you don’t need any of those. You can just reference your view property by its @id XML parameter, those properties would have the same name as declared in your XML file. More info can be found in official docs.
apply
, let
, and extension functions can be easily used to create elegant builders.
**2. A quick hack for beginners**During the first couple of days, you often stumble upon a problem: you don’t know how to write a rather simple Java expression in Kotlin. A simple trick is to write a piece of code in Java and then paste it into a Kotlin file. Thanks to guys in JetBrains, it gets automatically converted to Kotlin. Hacky, but works like a charm!
**3. Getting rid of unnecessary dependencies**Kotlin replaces a lot of third-party libraries, such as ButterKnife, Google Autovalue, Retrolambda, Lombok and some of the RxJava code.
As a software development team, the main challenge we have is delivering great products and being effective at getting the job done. Although to start developing effectively in Kotlin you need some prerequisite knowledge of functional programming, investing time to learn it really pays off. I believe Kotlin is a major improvement over conventional Android development, which allows us to deliver great apps on time, and with MUCH fewer bugs.
Feel free to ask questions, we will be grad to help others make the transition. Share your thoughts / comments below!
Programming is the most fun you can have with your clothes on.
John Guttag
UPD: _val_
does not actually mean ‘immutable’, but rather ‘read only’. See this article for details.
This post was originally published at UPTech Team blog. Follow us for more articles on how to build great products 💪
References