Kotlin is a relatively new JVM language that has been in active development by JetBrains since 2011.
It has seen a growing interest in Android community over the past few years, and eventually became the hottest topic in Android development after Google IO 2017, where an official support for Kotlin on Android was announced.
Unfortunately, even though many articles about Kotlin were published, there is not much objective information available, and many developers still contemplate whether a migration to Kotlin is the way to go.
In the remaining of this post I will attempt to provide a more complete list of considerations that should be taken into account when evaluating Kotlin as a replacement for Java.
Subjective comparison of Kotlin to Java:
Statements like “Kotlin is better than Java”, “Kotlin is more readable than Java”, “Kotlin is faster to develop with than Java”, while not supported by relevant and accurate data, all fall into category of subjective opinions.
Subjective opinions form when individual developers make one or more subjective judgements about subjects related to Kotlin or Java.
There are several issues associated with subjective judgement of developers:
- There are no quantitative metrics associated with subjective judgement.
- Subjective judgement is extremely biased.
- The biases of subjective judgement can differ substantially between developers.
Since there are no metrics associated with subjective judgements, opinions that were built upon these judgements are just reflections of developers’ pre-existing biases. Different developers might have vastly different biases, therefore the fact that some developers consider Kotlin a good (or bad) replacement for Java does not necessarily mean that other developers agree.
Furthermore, since there are no objective metrics, subjective disagreements can’t be resolved in objective ways, which often leads to so called “flame wars”.
Subjective judgement fallacy:
In order to demonstrate how subjective judgements can be misleading, let’s scrutinize one very common subjective opinion:
Kotlin is more readable than JavaCountless articles on the web
Theoretically, an experiment that attempts to measure readability differences between Kotlin and Java can be designed, but I’m not aware of any that was actually carried out. Therefore, as of today, this opinion is not backed by any data.
One aspect that many developers who praise Kotlin associate with readability is language’s syntax. The reasoning goes like this:
Kotlin has a better syntax, therefore it is more readableCountless articles on the web
The part about better syntax is another subjective judgement which can be debated by itself, but let’s assume for the sake of the argument that Kotlin’s syntax is indeed better. Does this imply that Kotlin is more readable?
In order to observe the effect of syntax on readability please read this “text”:
This “text” was hard to digest initially, but, gradually, became much easier to read. If you read it another two or three times, you will stop noticing that it is composed of a non-standard alphabet at all. Substitution of alphabet is not exactly a syntactic change, but it does demonstrate that external appearance is rarely a barrier to readability for a proficient reader.
We can extend this example to natural languages too. I know 3 languages which differ substantially from one another. Even though the languages are very different, I find it difficult to read texts in any of these languages only when I don’t understand the words that are being used. Whenever the text consists of words that I recognize and the context is familiar – I have no trouble reading it regardless of the language used.
Therefore, for me, the choice of a language does not affect readability, as long as the content and the context are understandable.
The same applies to programming languages.
When we begin using a new language we have a hard time understanding the source code and need to actively interpret each syntactic construct. However, as we read and write more code using a specific language, we gradually get accustomed to that language’s syntax, and, at some point, stop noticing the syntactic constructs at all.
I myself experienced this effect in handful of languages: Verilog, Bash, Perl, Tcl, Lisp, Java.
Based on the experience with the above languages I can tell you this: if one can get accustomed and stop noticing the parentheses in Lisp code, there is absolutely nothing in Kotlin’s syntax that can have a non-negligible effect on readability as compared to Java, even if it is “better”.
While we are on this subject, let me share with you my own subjective judgement about the factors that affect the readability of the source code.
Having read code written by other developers in many languages (the above list contains just the languages I was proficient with at some point; the list of all languages I used is longer), I made the following observation: developers who write readable and understandable code in one language, usually write readable and understandable code in other languages too.
Therefore, in my empiric subjective judgement, readability of the source code is independent of the choice of the language, and only depends on the skill of the author of the code and the skill of the reader (with the skill of the author being much more important).
If you still think that subjective opinions can be representative, then, at least, read and take into consideration the opinion of Robert “Uncle Bob” Martin expressed in this blog post.
Objective comparison of Kotlin to Java:
Contrary to subjective comparison, objective comparison uses quantitative metrics in order to either measure or estimate the real advantages of Kotlin over Java.
The idea of having a set of criteria that will objectively show whether one programming language is better than the other is very compelling, but there is one problem: as far as I know, there are no universal objective metrics associated with programming languages.
Given the fact that we can’t perform precise direct comparison, can we compare Kotlin and Java objectively at all? Yes! We can still estimate the magnitude of positive and negative effects that will come into play upon switching from Java to Kotlin, and then compare the outcomes and discuss their implications.
In order to estimate the best possible outcome for Kotlin, we will make the following assumptions:
- Developers can switch to Kotlin instantly
- Developers do not loose skill upon switching to Kotlin (e.g. developers with 2 years of Java experience magically gain 2 years of Kotlin experience)
- Kotlin is as stable as Java
- Tools for Kotlin are as mature as tools for Java
In practice, none of the above assumptions are justified, but it will be illustrative to have an idealistic figure to start with. Then, we will drop these assumptions and discuss the impact of the effects that occur in real world.
Estimation of the best case scenario for Kotlin:
Following the pattern proposed by Steve McConnell in his Code Complete book, we can see the software construction activity as being split into three sub-activities: detailed design, coding and debugging, developer testing.
Kotlin will have no effect on detailed design sub-activity (which is generally independent of the choice of a specific object-oriented programming language), therefore this part will require the same effort for both Kotlin and Java.
To my best knowledge, Kotlin has nothing revolutionary to propose in developer testing sub-activity either. Therefore, the effort required for developer testing will be the same too.
This leaves us with coding and debugging sub-activity.
How much effort can we spare on coding and debugging if we use Kotlin instead of Java? This is a hard question to answer and the number will vary greatly between developers (with some developers being more productive with Java). However, since we are looking for best case estimate, we can just assume that switching from Java to Kotlin will improve the productivity of developers during coding and debugging by 10% on average.
The improvement in productivity of 10% is astonishingly unrealistic number. It would be unrealistic even if we would type all the code by hand in a text editor. Given the functionality of today’s IDEs, this number becomes astronomically unrealistic. Given the fact that some developers will be more productive with Java, this number is just nonsense.
I don’t mind to use such an unrealistically favorable for Kotlin estimate because I know that whatever unrealistically positive effects we will get as a result of this estimate, these positive effects will be swamped by the negative effects introduced once we drop some of our “idealistic assumptions”.
So, 10% improvement in coding and debugging – how much faster will we deliver new products to our users?
Take a look at this chart from Code Complete that shows the proportion of various activities on software projects:
Figure 27-3 Construction activities dominate small projects. Larger projects require more architecture, integration work, and system testing to succeed. Requirements work is not shown on this diagram because requirements effort is not as directly a function of program size as other activities are (Albrecht 1979; Glass 1982; Boehm, Gray, and Seewaldt 1984; Boddie 1987; Card 1987; McGarry, Waligora, and McDermott 1989; Brooks 1995; Jones 1998; Jones 2000; Boehm et al. 2000).
Code Complete, 2nd edition
According to this chart from Code Complete, for a non-trivial software project (larger than 10k lines of code), coding and debugging takes less than 20% of the total project’s effort.
Therefore, our assumption of 10% increase in productivity during coding and debugging leads to reduction of less than 2% in total effort required in order to complete a non-trivial software project.
For example, on a project that requires 5 man-years to complete (which is relatively large project for Android), 2% of total effort accounts to:
5 man-years * 12 * 4 * 5 * 0.02 = 24 (man-days)
If we could indeed reduce the project’s effort by 24 man-days, then it would be a very good argument in favor of switching from Java to Kotlin. However, we shall remember that the above positive estimate is idealistic and was derived based on unrealistic assumptions.
Let’s see how this idealistic estimate compares to estimates of real-world effects that are inevitable upon switching to another programming language.
In order to perform the best case estimation we assumed that developers can switch from Java to Koltin instantly.
In practice, despite Kotlin being very similar to Java, developers will need to spend some time learning it, and then some more time in order to make adjustments to development practices and tools. Ramp-up time will be different between developers: some developers will be able to switch in 3-4 days, while others will need 10 days or more.
Let’s take an optimistic figure of 5 days as an average amount of time it takes a developer to switch from Java to Kotlin.
On a project that requires 5 man-years to complete, there will be 3-5 developers (optimal case). Average switching time of 5 days per developer on such a project will sum up to a total switching time of 15-25 man-days.
Looks like the effort reduction that could have been (optimistically) achieved by switching to Kotlin is comparable to the total effort required for performing the switch.
Developers skill loss:
Ability to work efficiently with a specific programming language is a skill.
We have already discussed one aspect of this skill (code readability), but there are many more. When switching from one language to another, some portion of the skill with the old programming language might apply to the new one, while the rest of the skill will be lost.
In order to assess the effect of programming language skill loss on the project’s effort we will be using “Language and Tools Experience” multiplier from Cocomo2 estimation model:
Language and Tool Experience (LTEX)
This is a measure of the level of programming language and software tool experience of the project team developing the software system or subsystem. Software development includes the use of tools that perform requirements and design representation and analysis, configuration management, document extraction, library management, program style and formatting, consistency checking, planning and control, etc. In addition to experience in the project’s programming language, experience on the project’s supporting tool set also affects development effort. A low rating is given for experience of less than 2 months. A very high rating is given for experience of 6 or more years, see Table 31.
Cocomo 2 Model Definition Manual
For example, let’s assume that we have a team of Java developers that have 1 year of language experience on average, and we want to migrate to Kotlin.
Since Kotlin is very similar to Java and is compatible with many Java tools, we can optimistically assume that after the initial ramp-up the developers will fall into the bucket of 6 months experience (instead of less than 2 months). Under this assumption, in order to estimate additional effort due to skill loss, the total nominal effort of the project should be multiplied by 1.09.
On a project that requires 5 man-years to complete using Java while staffed with developers that have 1 year of Java experience on average, the estimated total additional effort due to switching to Kotlin will be a whooping 108 man-days.
The additional effort due to skill loss is four times higher than the reduction of effort that could have been achieved by switching to Kotlin.
Language and tools stability and maturity:
There is a widespread claim that Kotlin is production ready language. These claims are probably justified because Kotlin is already being in use in some projects.
However, when compared to Java, Kotlin is unstable and young language.
Some developers think that Kotlin’s instability is an advantage – the language evolves and new features and improvements become available faster. In my opinion, this is a very simplistic view of this matter.
The following is the very first statement in Kotlin 1.1.4 release notes (the latest release as of this writing):
Fixes a major performance regression in the IntelliJ IDEA pluginKotlin 1.1.4 release notes
I don’t know what kind of regression is this and how many projects were affected, but my mind automatically translates the combination of words “major performance regression” into “many hours of wasted developers time”.
In addition, if you read through comments to release notes, you’ll notice that many people have troubles with migrations. One comment on release 1.1.2 even suggested that this “patch” release introduced breaking (non backward-compatible) changes.
In contrast, if you read through release notes of Oracle’s JDK8, you will observe much less drama. Most of the changes are related to security improvements.
So, when compared to Java, Kotlin is unstable and immature language – how this can affect the projects that migrate to Kotlin? In order to answer this question, we will use “Platform Volatility” effort multiplier from Cocomo 2 estimation model:
Platform Volatility (PVOL)
“Platform” is used here to mean the complex of hardware and software (OS, DBMS, etc.) the software product calls on to perform its tasks. If the software to be developed is an operating system then the platform is the computer hardware. If a database management system is to be developed then the platform is the hardware and the operating system. If a network text browser is to be developed then the platform is the network, computer hardware, the operating system, and the distributed information repositories. The platform includes any compilers or assemblers supporting the development of the software system. This rating ranges from low, where there is a major change every 12 months, to very high, where there is a major change every two weeks, see Table 25.
Cocomo 2 Model Definition Manual
You might’ve noticed that programming languages do not appear explicitly in the description of this effort multiplier, but compilers and assemblers do. In my opinion, programming languages were not included explicitly because all the projects that Cocomo 2 was derived from used stable languages.
Since compilers and assemblers belong to this effort multiplier, we can extrapolate it to the programming language and the associated tools too.
On this scale of platform volatility, Java would score “very low”, while Kotlin is in the “low” range or higher. It is probably higher because it has inter-dependencies with other tools which increase the risk of compatibility issues.
Since the multiplier for “very low” platform volatility rating is not available, we need to estimate it.
Looking at the progression of multipliers from “very high” to “low” ratings, I think we can safely assume that the multiplier for “very low” rating is not higher than 0.82.
If we stick to these assumptions (which are favorable for Kotlin), then, on a project that requires 5 man-years of nominal effort to complete, using Kotlin will result in a total effort of 1044 man-days, whereas using Java will result in a total effort of 984 man-days.
Choosing to implement such a project with Kotlin instead of Java will add 60 man-days to the total effort.
The addition effort due to language and tools instability is more than twice higher than the reduction of effort that could have been achieved by switching to Kotlin.
Summing up all the factors:
The project that I chose to discuss as an example required a nominal effort of 5 man-years to complete.
According to our estimations above, if this project would be implemented in Java by developers who already have 1 year of Java experience on average, the total effort would be:
5 man-years * LTEX(Java) * PVOL(Java) = 984 (man-days)
If the same project would be implemented in Kotlin by developers who have very little or no experience with the language, the total effort would be:
5 man-years * LTEX(Kotlin) * PVOL(Kotlin) * 0.98 + T_ramp_up = 1115 + 5 * N_developers (man-days)
The total estimated additional effort due to choosing Kotlin over Java is
131 + 5 * N_developers (man-days).
A note about estimations:
Following our estimation discussion, we got a convenient single point values for efforts associated with Kotlin and Java.
In practice, however, single point values are not estimates at all – they are just guesses. A real estimate must always have an associated uncertainty. In other words – estimates express ranges of possibilities and not single point values.
We ended up using single point values instead of ranges because I converted all estimates to a single point values by choosing the most favorable value for Kotlin from the estimated range.
For example, when discussing the effect of Kotlin on coding and debugging activity, I chose the enormous 10% productivity increase value from a range of possibilities that I estimated to be [-5%, 10%]. In other case, when we discussed the average time it takes developers to switch to Kotlin, I chose the minimal 5 days value from a range that I estimated to be [5d, 21d].
In addition, we used the effort multipliers specified for Cocomo 2 estimation model. These multipliers are not universal truths and, in the most general case, should probably also have associated uncertainty. I attempted to account for this uncertainty by assigning to Kotlin rating levels that are more favorable than what I actually think it deserves.
Needless to say that the single point values that we got can’t be precisely correct. In order to see a more complete estimation picture we could perform Monte Carlo simulation using the actual estimates. This technique would allow us to observer the distribution of possible outcomes and understand what kind of outcome is the most probable.
Keep in mind that since we collapsed the estimates into single point values that are most favorable for Kotlin, the other possible outcomes will show a greater overhead associated with switching to Kotlin. Therefore, the single point values that were stated in the previous section are probably the most favorable for Kotlin from the entire set of possible outcomes.
I opened this post by showing how subjective judgements of developers can be misleading in comparison of programming languages.
Then I discussed the difficulties associated with objective comparison of programming languages, and performed a series of estimates in order to understand how Kotlin stacks against Java in context of total effort required for completion of a software project. While performing the estimates, I consistently used the values from an estimated range that are most favorable for Kotlin.
From this analysis it looks like switching from Java to Kotlin will result in increased total effort required for completion of software projects.
More effort means that the companies that switch to Kotlin will need to spend more money in order to get the same functionality, and the users will need to wait longer for the products.
To some developers, this might be a very surprising and not an easy conclusion to accept.
At the end of a day, Google did decide to support Kotlin for Android development. Is it possible that no one at Google could perform a similar analysis in order to understand the downsides of switching to a new language?
I think that Googlers are very smart people, and I believe that they did perform a very deep analysis before a decision to support Kotlin was made.
In the next post we will discuss why would Google invest in support for Kotlin, while it should be clear from a quick analysis that it will not be beneficial to Android community.
Edit: while making my research for the aforementioned post, I realized that before analyzing Google’s motivation for adoption of Kotlin, it is worth investing time into discussion of JetBrain’s motivation behind invention of this programming language. You can read my thoughts on this subject in this post.
Please leave your comments and questions below, and consider subscribing to our newsletter if you liked this post.