On the adoption, usage and evolution of Kotlin features in
Android development
Bruno Gois Mateus
Université Polytechnique Hauts-de-France, France
Matias Martinez
Université Polytechnique Hauts-de-France, France
ABSTRACT
Background:
Google announced Kotlin as an Android ocial pro-
gramming language in 2017, giving developers an option of writing
applications using a language that combines object-oriented and
functional features.
Aims:
The goal of this work is to understand
the usage of Kotlin features considering four aspects: i) which fea-
tures are adopted, ii) what is the degree of adoption, iii) when are
these features added into Android applications for the rst time,
and iv) how the usage of features evolves along with applications’
evolution.
Method:
Exploring the source code of 387 Android ap-
plications, we identify the usage of Kotlin features on each version
application’s version and compute the moment that each feature
is used for the rst time. Finally, we identify the evolution trend
that better describes the usage of these features.
Results:
15 out of
26 features are used on at least 50% of applications. Moreover, we
found that type inference, lambda and safe call are the most used
features. Also, we observed that the most used Kotlin features are
those rst included on Android applications. Finally, we report that
the majority of applications tend to add more instances of 24 out
of 26 features along with their evolution.
Conclusions:
Our study
generates 7 main ndings. We present their implications, which
are addressed to developers, researchers and tool builders in order
to foster the use of Kotlin features to develop Android applications.
CCS CONCEPTS
Software and its engineering Language features.
KEYWORDS
Android, Kotlin, Features adoption, Evolution trends
ACM Reference Format:
Bruno Gois Mateus and Matias Martinez. 2020. On the adoption, usage
and evolution of Kotlin features in Android development . In ESEM ’20:
ACM / IEEE International Symposium on Empirical Software Engineering and
Measurement (ESEM) (ESEM ’20), October 8–9, 2020, Bari, Italy. ACM, New
York, NY, USA, 12 pages. https://doi.org/10.1145/3382494.3410676
1 INTRODUCTION
Currently, the Android platform is the largest mobile platform,
with more than 2 million applications published in the ocial store,
Permission to make digital or hard copies of all or part of this work for personal or
classroom use is granted without fee provided that copies are not made or distributed
for prot or commercial advantage and that copies bear this notice and the full citation
on the rst page. Copyrights for components of this work owned by others than ACM
must be honored. Abstracting with credit is permitted. To copy otherwise, or republish,
to post on servers or to redistribute to lists, requires prior specic permission and/or a
fee. Request permissions from [email protected].
ESEM ’20, October 8–9, 2020, Bari, Italy
© 2020 Association for Computing Machinery.
ACM ISBN 978-1-4503-7580-1/20/10.. . $15.00
https://doi.org/10.1145/3382494.3410676
Google Play. Since the rst release of Google’s mobile operating
system, developers have been developing applications mostly using
Java and, in some specic scenarios using C++. However, in 2017,
when Google announced Kotlin as an Android ocial programming
language, developers gained another option to write applications.
Moreover, in 2019, Google announced that Android development
would become increasingly ‘Kotlin-rst’, which means that new
APIs and features will be oered rst in Kotlin [
20
]. After this
announcement, studies investigating how developers were dealing
with the adoption of Kotlin as an ocial language concluded that
developers believe that the use of Kotlin can improve the code
quality, readability, and productivity [29, 33].
Kotlin provides a dierent approach to write applications be-
cause it combines object-oriented and functional features, some
of them not present in Java or not available for Android devel-
opment [
1
]. Despite the increasing use of Kotlin among Android
developers, to the best of our knowledge, there is no study in the
literature about the adoption of Kotlin features by Android develop-
ers. As pointed by Mazinanian et al
. [31]
, the lack of this knowledge
negatively aects four audiences: i) researchers are not aware of
the research gaps (i.e., the actual unsolved problems faced by the
developers) and thus miss opportunities to improve the current
state of the art, ii) language and library designers do not know
if the developers eectively use the programming constructs and
APIs they provide are eectively used by the developers, or are
rather misused or underused, iii) tool builders do not know how
to tailor their tools, such as recommendation systems and code
assistants, to the developers’ actual needs and practices when using
Kotlin, iv) developers are not aware of the good and bad practices
related to the use of Kotlin features.
For those reasons, the goal of this paper is to understand the
usage of Kotlin features on Android applications. In order to explore
the usage of Kotlin features, we considered four aspects of features
usage: i)
which
features are adopted, ii)
what
is the degree of adop-
tion, iii) when are these features added into Android applications
for the rst time, and iv)
how
the usage of features evolves along
with applications’ evolution.
To carry out our experiment, we used the largest publicly avail-
able dataset with open-source Android applications written in
Kotlin [
19
], which has 387 applications with Kotlin code. To study
the adoption of Kotlin features, we extracted features from the
source code of applications, and we identied when features were
used for the rst time. To understand how the use of features
evolves, we analyzed the code repository of each application (i.e.,
Git) to mine the features used on each version (commit). Then, we
automatically assigned to each application-feature pair
(a, f )
an
evolution trend that better describes the use of
f
along with the
evolution of
a
. Dierent from other studies that focus on manual
arXiv:1907.09003v3 [cs.SE] 27 Jul 2020
ESEM ’20, October 8–9, 2020, Bari, Italy Bruno Gois Mateus and Matias Martinez
classication of evolution trends [
22
,
26
], our method is completely
automated. Finally, we computed the most frequent evolution trend
associated with a feature.
As result of our research, this paper makes the following contri-
butions:
A study about the adoption of Kotlin features in the devel-
opment of Android applications.
A methodology to automatically identify and classify trends
of feature adoption during application’s evolution.
A study that shows how Kotlin features evolve during the
applications’ evolution.
A list of 7 main empirical ndings about the usage and evolu-
tion of Kotlin and its implications to developers, researchers,
tool builders.
All the data presented in this paper is publicly available in our
appendix: https://github.com/UPHF/kotlin_features
2 DESCRIPTION OF KOTLIN’S FEATURES
2.1 What is Kotlin?
Kotlin is a programming language that runs on the Java virtual
machine. It combines object-oriented and functional features and,
as it has 100% interoperability with Java. Therefore, developers can
use it to write new les in an existing Java project or to write a new
application using Kotlin from scratch. Moreover, the ocial IDE for
Android development, Android Studio, provides rst-class support
for Kotlin, including a built-in tool to convert Java-based code
to Kotlin. Android applications are historically developed using
Java and, by default, the Android platform is compatible with Java
6, which means that several new Java features, such as Lambdas,
cannot be used for developing Android apps. Using Android Studio
3.0 or later, developers can use any feature from Java 7 and some
features from Java 8, such as Lambdas. However, that requires
to use a minimum target Android SDK version [
12
]. Therefore,
the announcement made by Google brought the possibility for
developers to use Kotlin instead of Java to write code for Android
and, consequently, to use Kotlin features not supported by Java.
2.2 Selection of Kotlin features
When a new programming language is released, it oers developers
a set of language features. Other languages could already provide
some of these features, whereas other features can be completely
new. In this paper, we exclusively focus on features that are avail-
able in Kotlin but not in Java. Our goal is to study how Android
developers use programming features that were not fully available
for developing Android applications before the release of Kotlin.
Despite the focus of this study, we claim that the methodology
presented could be applied to investigate the usage of Kotlin fea-
tures in a context other than mobile development (e.g., server-side
applications).
To identify Kotlin features not available in Java, we inspected
the Kotlin ocial website. First, we extracted 13 features from a
document that compares Kotlin and Java [
1
]. Then, we extracted 4
features from Kotlin’s release notes, which were not mentioned in
the comparison document (coroutine as experimental feature and
type alias from release 1.1 and contract and inline class from release
1.3). Finally, we passed over the Kotlin Reference [
24
] and identied
7 more features. Table 1 summarizes the features that we target in
this study.
Table 1: Kotlin features and their release version.
ID Feature Release
version
Normalization Criteria
1 Type inference 1.0 # of variable declarations
2 Lambda 1.0 LLOC
3 Inline function 1.0 # of named functions
4 Null-safety (Safe and Unsafe calls) 1.0 LLOC
5 When expressions 1.0 LLOC
6 Function w/arguments with a default
value
1.0 # of functions + # of construc-
tors
7 Function w/ named arguments 1.0 # of function calls
8 Smart casts 1.0 LLOC
9 Data classes 1.0 # of classes
10 Range expressions 1.0 LLOC
11 Extension Functions 1.0 # of named functions
12 String template 1.0 # of strings
# of properties
13 Delegation (Super and Property) 1.0
# of inheritances
14 Operator Overloading 1.0 # of named functions
15 Singleton 1.0 # of object declarations
16 Companion Object 1.0 # of object declarations
17 Destructuring Declaration 1.0 # of variable declaration
18 Inx function 1.0 # of named functions
19 Tail-recursive function 1.0 # of named functions
20 Sealed class 1.0 # of classes
21 Type aliases 1.1 LLOC
22 Coroutine (experimental) 1.1 LLOC
23 Contract (experimental) 1.3 LLOC
24 Inline class 1.3 # of classes
3 METHODOLOGY
The goal of this paper is to understand the usage of Kotlin features
on Android applications. The following research questions guide
our study:
RQ
1
: Which Kotlin features are adopted by Android devel-
opers?
RQ
2
: When do Android developers introduce Kotlin features
during applications’ evolution?
RQ
3
: How the usage of Kotlin features evolves along with
the evolution of Android applications?
In this section, we present the study design applied to respond
to these research questions. First, we present a method to detect
Kotlin features from source code (Section 3.1). Second, we present
a method to identify when these features are used for the rst time
within an application (Section 3.2). Finally, we present a method to
classify the use of features along with the application’s evolution
(Section 3.3).
3.1 Identication of Kotlin features
For responding to our research questions, we need to identify the
use of Kotlin features from the applications’ source code. For that
reason, we built a tool that given as input a Kotlin source code le
(.kt le) and returns a list of all features found in that le.
We built the tool as follows. Our feature detection tool operates
on the abstract syntax tree (AST) provided by the Kotlin compiler
API. For each feature presented in Table 1, we rst manually inves-
tigated how a feature is represented on an AST. Then, we encoded
dierent analyzers for detecting feature instances on ASTs. We en-
coded analyzers successfully for the 24 features presented in Table 1.
On the adoption, usage and evolution of Kotlin features in Android development ESEM ’20, October 8–9, 2020, Bari, Italy
We built 26 analyzers because we encoded two analyzers for two
features: Null-safety and Delegation. We split the Null-safety feature
in two: 1) Safe call that provides information about the usage of the
safe call operator ‘?’ and 2) Unsafe call that tells whether developers
use the not-null assertion operator ‘!!’ that we will refer as unsafe
operator. We also split Delegation in two features: 1) Super Dele-
gation and 2) Property Delegation. Moreover, regarding the feature
Type inference, our analyzer focuses on a single scenario: variable
declaration (e.g. “var a=10;”, the type of a is inferred (int)).
To the best of our knowledge, there is no benchmark of Kotlin
features usage that we could use for evaluating our tool. Therefore,
we run an experiment based on manual verication to evaluate
its precision. We executed our tool over the last version of each
application from our dataset (387 applications), which returned
a list of features instances found, with their respective locations
(le name and line number). This information allowed us to verify
whether each reported feature instance was present or not at the
reported les. To achieve a condence level of 95% and a condence
interval of 10% we checked 96 instances of each feature, randomly
selected. The evaluation results, available on our appendix, showed
the precision of the tool is 100%.
1
To measure the recall of our
tool, both authors manually analyzed 100 les randomly selected.
Then, we executed our tool over this set of les and calculated the
recall. we found a recall of 100% for all features, but coroutine (an
experimental feature). Our strategy based on keywords could not
identify all possible coroutines, resulting in a recall of 91%.
3.2 Mining Kotlin Features from Applications
3.2.1 Analyzing Feature Evolution by Inspecting Commits. To ana-
lyze the usage of features along with the history of one application,
we created another tool that takes as input a Git repository and
produces, for each version
v
(i.e., commit) the number of features
found on
v
. The tool navigates through the commits of the active
branch, in general, the master branch. Given a Git repository, it
starts from the oldest commit, and for each commit, it computes the
number of features by invoking our feature detection tool described
in Section 3.1. When a repository is analyzed, our tool generates a
JSON le. This le has for each commit, the number of features of
each studied feature grouped by le. This tool is built over Com-
ing [
30
], a framework for navigating Git repositories that allow
users to plug-in their source code analyzers.
3.2.2 Summarizing use of Kotlin features. To answer the rst re-
search question (RQ
1
), we processed the output of our feature
evolution tool (Section 3.2.1). For each feature
f
, we counted the
number of applications that have at least one instance of
f
in any
commit and the total number of instances in the last commit of
every application.
3.2.3 Normalization of feature instances. As the applications may
have dierent sizes, we normalized the number of instances fol-
lowing the criterion presented in Table 1. We could normalize each
feature with a unique metric of size, such as LLOC. However, we
1
To nd the minimum number of instances to analyze (96), we compute the condential
level by considering as sample size the number of instances of the most frequent feature,
which was type inference with 165,667 instances.
consider that it would be more meaningful (and would better de-
scribe the use of a feature) if we normalize each feature
f
by a
metric that is related to
f
. For instance, it gives more information
to say that an application has 1 data class each
N
classes, rather
than reporting that it has 1 data class every Y lines of code.
Now, we detail the normalization process. As explained in Sec-
tion 3.1, our analyzer of type inference considers only variable dec-
larations. Thus, we normalized the instances of this feature by the
number of variables declared. Since destructuring de clarations break
down objects into (declaring) multiple variables, we also normalized
its instances by the number of variables declared.
In Kotlin, every function declared is a named function node in
the AST. Thus, we normalized the number of instances of extensions
functions by the number of named functions. Since only named func-
tions might receive the modier inline, we used their number to
normalize the number of inline functions. For the same reason, we
used the same criterion to normalize the number of tail-recursive.
Analogously, we normalized the number of data classes, sealed
classes and inline class by the number of classes. Additionally, the
number of named functions was also used to normalize the num-
ber of operator overloading because, by denition, an overloaded
operator is a named function that receives the modier operator.
Arguments with a default value can be used in named functions
and constructors. Thus, we normalized function with arguments with
a default value by the number of named functions and constructors.
Named arguments are used when a method/function is called. Con-
sequently, we normalized the number of function calls with named
arguments by the number of function calls. Besides, since only
strings might have a string template, we normalized the number
of string templates by the number of strings. Concerning Kotlin
delegations, we normalized the number of properties delegated
by the number of properties. Moreover, as sup er delegation is an
alternative to inheritance, we normalized their instances by the
number of classes. In Kotlin, object expressions are used to declare
singletons and companion object. Consequently, we normalized the
number of singleton and companion object by the number of object
declaration. For the remaining features, we normalized them by
LLOC because we could not nd a better criterion.
3.2.4 Identifying the first use of Kotlin features. For responding to
RQ
2
, we computed, for each application
a
and for each feature
f
,
the rst commit
C
f a
that introduces an instance of
f
into
a
. Finally,
we dened a metric, named introduction moment,
m
af
[
0
, n]
where
n
is the number of days between the rst Kotlin commit and
the last commit, that measures how long after the initial commit a
feature
f
was introduced into
a
. It is expressed in days. For instance,
m
af
=
0 means that feature
f
was introduce into
a
in the same
day of the rst Kotlin commit,
m
af
=
5 means that
f
was added
in the 5 days after the Kotlin introduction, and
m
af
= n
, means
that f was introduced in the same day of the last commit.
3.3 Classifying the use of features along with
the application’s evolution
The goal of
RQ
3
is to detect trends that describe the usage evolution
of features along with the applications’ history. For example, we
want to detect applications where the use of a particular feature is
constant, increases or decreases along with its evolution.
ESEM ’20, October 8–9, 2020, Bari, Italy Bruno Gois Mateus and Matias Martinez
3.3.1 Feature evolution on applications. To study the use of a fea-
ture
f
along with the history of one application, we rst counted
the number of instances of f on each applications’ version.
3.3.2 Classification of feature evolution trend. To classify each pair
of application-feature
(a, f )
and nd the trend that best describes
the evolution of a feature
f
in the history of an application
a
,
we dened a set of evolution trends following a data-driven ap-
proach. First, we automatically plotted a two-dimension plot for
each application-feature
(a, f )
where the axis X corresponded to
the number of commits (chronologically order) from
a
, and the axis
Y was the number of instances of a feature
f
. Then, we iteratively
analyzed the generated plots. For each of them, we rst described
the trend we observed in two ways: 1) natural language description
(e.g., “Instances increase”), 2) mathematically (e.g., “y=ax+b”). Then,
we checked whether a similar trend had been seen before based on
such descriptions. We repeated this last step until no new trend be
found after analyzing dozens of plots. To avoid bias, both authors
have analyzed the same plots separately, and later, we compared
and discussed the result found. We found 11 unique evolution trends
that were described by 6 dierent mathematical formulas.
Other works have previously dened evolution trends, such as
Hecht et al
. [22]
and Malavolta et al
. [26]
. Both studies have used
their trends to classify manually evolution plots. On the contrary,
the denition of our evolution trends was motivated by the need
to classify trends automatically, which guarantees i) scalability (i.e.,
thousands of apps-feature pairs to classify) and ii) the replication
(analysis of other applications) of this study.
3.3.3 Considered trends and formulas. We established 11 major
feature evolution trends to answer RQ3. An example of each of
them is shown in Figure 1. These trends are:
Constant Rise (CR) describes features that once they are intro-
duced (i.e., used for rst time in an application), developers tend to
add more instances of this feature in future application versions.
Therefore, the number of instances of increases at a constant rate,
i.e., linearly along with the application’s evolution.
Constant Decline (CD) describes features that once they are intro-
duced, developers tend to remove them gradually in future applica-
tions’ versions. Therefore, along with the application’s evolution,
the number of feature instances decreases at a constant rate.
Stability (S) describes features whose numbers of instance remain
the same after its introduction, along the application’s evolution.
We used the linear function given by the formula y = ax + b to
detect CR, CD and S. Since in linear function, the rate of change
(given by coecient
a
) is always constant, we could classify the
application’s trend into: (CR) when
a >
0, which implies on constant
increase; (CD) when
a <
0, which implies on constant decrease;
and (S) when a = 0, which determines a constant behavior.
Sudden Rise (SR) describes those features that the number of
occurrences grows suddenly after relative stability along with the
applications’ history. Using this trend, we are able to identify those
features that present a small number of instances in the rst com-
mits and then, at the following commits, on each commit, developers
introduce signicantly more instances.
Sudden Decline (SD), analogously, describes the opposite behavior
of SR, where the number of feature instances decreases suddenly.
Features that present many instances since the rst commits and
then, suddenly, start to be removed, and this behavior continues in
the next consecutive commits.
We used the exponential function given by the formula
y =
ab
x
+ c
to detect SR and SD. In this formula, the rate of change
is given by coecient
b
. When
b
is greater than 1, the value of
y
increase as
x
increases. On the other hand, if
b
is 0
< b <
1,
the value of a function increases as the value of
x
decrease. Then,
considering the value of
b
we classied evolution trends better
described by an exponential function in two trends, SR and SD.
Sudden Rise Plateau (SRP) describes features which most of its in-
stances are introduced in the rsts commits of an application. Then,
during the rest of the application’s history, only a few instances are
introduced.
We used the logarithmic function given by the formula
y =
a log
e
(bx) + c
to detect SRP. In this case, unlike the exponential
formula, the rate of change always decreases with time.
Plateau Gradual Rise (PGR) describes those feature which once
they are introduced, the number of instances tends to remain the
same during an interval of commits and then presents a sudden
increase in few consecutive commits, and nally presents a stable
behavior again.
Plateau Gradual Decline (PGD) is similar to the trend PGR, this
trend describes those features that the number of instances starts
and nishes stable. However, on the contrary of PGR, here, the
change that happens between the periods of stability is a reduction
of the number of instances in a few consecutive commits.
Plateau Sudden Rise (PSR) is similar to PGR. However, using this
trend, we aim to detect features that present: a) a stability period at
the beginning of the application’s evolution b) a transition period
containing only one commit and c) stability period at the end of
the application’s evolution.
Plateau Sudden Decline (PSD) analogously to PSR, this trend is a
special case of PGD where the change between the two periods of
stability has a marked decrease in the number of instances, in two
consecutive commits.
We used the Sigmoid function,
y =
L
1+ϵ
(
k(xx 0))
+ b
, to detect
the trends PGR, PGD, PSR and PSD. A Sigmoid is a bounded function
where
y
can assume values from
L + b
to
L + b
. Additionally,
when
L b >
0,
y
approaches
L + b
as
x
approaches
+
and
approaches
L + b
as
x
approaches
−∞
. On the other hand, we
observe the opposite behavior, when
Lb <
0. While
x
0 is Sigmoid’s
midpoint, which marks the middle of the S-curve,
k
determines
the steepness of the curve. The PGR trend is characterized by the
lowest the number of instances (
L + b
) at the beginning of the
application history and the highest value (
L + b
) of the number of
instances in the end. Moreover, the transition between the lowest
and the highest values is characterized by a gradual rise, in a small
number of commits, when developers introduce a considerable
number of instances. The PGD trend follows the opposite behavior,
starting from the highest number of instances and nishing with the
lowest number of instances. The dierences between PGR and PSR,
and PGD and PSD, is determined by the coecient
k
, where a small
value of coecient
k
makes the slope of a Sigmoid function be
completely vertical.
On the adoption, usage and evolution of Kotlin features in Android development ESEM ’20, October 8–9, 2020, Bari, Italy
(a) Constant
Rise
(b) Constant
Decline
(c) Stability (d) Sudden Rise (e) Sudden
Decline
(f) Sudden Rise
Plateau
(g) Plateau
Gradual Rise
(h) Plateau
Gradual
Decline
(i) Plateau
Sudden
Rise
(j) Plateau
Sudden
Decline
(k) Instability
Figure 1: Example of evolution trends. The x-axis shows the evolution of an application, i.e., commits, and the y-axis shows
the number of occurrences of a feature.
Instability (I): describes features that the number of instances
alternates between an increase and a decrease during the applica-
tion’s evolution.
We used the polynomial function given by the formula
a
n
x
n
+
a
n1
x
n1
+ · · · + a
2
x
2
+ a
1
x + a
0
, where
n
is the degree of the
polynomial and
a
n
>
0 to detect the Instability trend. Since the
degree of a polynomial determines the number of minimum and
maximum (at most
deдree
1) given an open interval, using this
formula we detected those features which the number of instances
along the application’s evolution form a curve with two or more
minimum or maximum.
3.3.4 Finding the formula that beer describes the feature evolution.
To match a feature evolution trend from one application with one
of the studied trends, we applied the following methodology:
Obtaining the series of the number of instances per application. As
explained in Section 3.2, given one application, our tool’s execution
gives each feature’s number of instances that each application’s
version (i.e., commit) has. Therefore, for each application
a
, we
generated a series of values
y
xa
= {vax
1
, va x
2
, .., vax
n
}
where
vax
i
corresponds to the number of instance of feature
f
detected
in the
i
-version of
a
(corresponding to the
i
-th commit considering
chronological order, starting with the rst version that introduces
x
). That is, the rst element contains the number of features in the
rst version that introduces f .
Computing formulas’ coecients by tting the series. For each se-
ries
y
xa
from a pair application-feature
(a, x)
, and for each formula
f
presented in 3.3, we used non-linear least squares to t function
f
to data
y
xa
. This gives as result a set of coecients (
α
1
, ..,
α
n
)
for
f
that correspond to the optimal values so that the sum of the
squared residuals SS
r eд
(Formula 1) is minimized.
SS
res
=
|versions a |
Õ
i
(y
xa
i
f
i
) (1)
The number of coecients generated varies according to the
formula
f
: for linear, the number of coecients is two, whereas for
a polynomial of 4 degrees is 5. For executing the tness of data, we
used the function ‘curve_t’ from library SciPy [25].
Post-Processing formulas and coecients. This step has two goals:
a) simplify polynomial formulas and b) discard some Sigmoid func-
tions which do not have a clear S-shape considering the domain
applied
[
0
,
#
commits
1
]
. We simplify those polynomial formulas
whose the coecient
a
n
is close to zero (i.e.,
<
than 0.0001), because
these evolution trends can be similarly described by a polynomial
n
1 degree. We also discard Sigmoid functions where the coecient
x
0
, i.e., the Sigmoid’s midpoint, is outside the range of commits
[
0
,
#
commits
1
]
, because in these cases only one plateau could be
in the commit range. Therefore, these cases do not congure any
of the studied trends modeled with the Sigmoid function.
Choosing the formula that best represents a feature evolution trend.
Once we computed the coecients for each formula, we chose, for
each pair
(a, x)
, the formula that yields less error to predict the
values of
y
xa
. We call it
f
best _ax
. Thus, this formula is considered
as that one that best represents the feature evolution trend among
all formulas we consider in this experiment (Section 3.3). We based
our choice on a statistical measure named R-squared (Coecient of
Determination) which measures how close the data are to the tted
formula. R-squared (R
2
) is always between 0 (bad) and 1 (good).
When two formulas
f
1 and
f
2 produce the same
R
2
values
within a small positive delta (0.01 in our experiment), we prior-
itized formulas with the smallest quantity of coecients, that
is:
Linear >> Exponential >> Loдarithmic >> Siдmoid > >
Polynomial.
Summarizing of best formulas. For each feature
x
and formula
f
, we count the number of applications that have
f
as the best
formula (Section 3.3.4). The result from this step helps us to explain
the most frequent evolution trend associated with each feature.
3.4 Evaluation dataset
In this paper, we studied applications from FAMAZOA
2
[
19
], a
dataset that has 387 open-source Android applications written
fully or partially in Kotlin. It contains applications collected from
3 sources: AndroidTimeMachine [
18
], AndroZoo [
6
] and F-Droid
3
Those apps have a median of 6 contributors, 56 les, 3984 lines of
Java/Kotlin and 64.08% of them were updated in the last 6 months.
4 RESULTS
4.1 RQ1: Which Kotlin features are adopted by
Android developers?
To answer this research question, we applied the method described
in Section 3.2, and Figure 2 summarizes its results. For each feature,
it shows the percentage of applications that have used that feature
at least once (considering all the version of those apps). In addi-
tion, Figure 3 shows the distribution of the normalized number of
occurrences of each feature per application (considering the latest
version of each one).
We observed that the most used feature is type inference with
381 out of 387 (98%) applications having at least one instance of
this feature, as Figure 2 shows. We found that a median of 77% of
variable declarations do not have their type explicitly declared, as
Figure 3 displays. However, we noticed some applications whose
2
https://uphf.github.io/FAMAZOA/versions/v3
3
http://f-droid.org
ESEM ’20, October 8–9, 2020, Bari, Italy Bruno Gois Mateus and Matias Martinez
Figure 2: Percentage of applications that use a feature. Each
bar corresponds to a feature and contains on top the number
of applications that use that feature.
Figure 3: Kotlin features normalized.
all variables have their type inferred as well. Therefore, we con-
cluded that developers can write code more concisely, avoiding
type declaration when the type is self-explained in the assignment.
Lambda is the second most used feature, being found in 370 out of
387 (95%) applications with a median of 71 instances per application.
The fact that Android applications rely on callbacks to interact
with the Android platform [
45
] could be seen as a reason for the
number of instances found. However, a high number of instances,
especially when they are nested, could lead developers to write
code with poor readability. In Kotlin, developers do not need to
name the parameter of a single parameter lambda function. In this
case, it is automatically named as ‘it’. Therefore, a chain of nested
lambdas using this mechanism might be hard to read. For that
reason, JetBrains once considered removing the ‘it’ parameter [4].
Safe call is the third most used feature. We found 348 out of
387 (89%) applications where safe calls were found, with a median
of 28 occurrences per application. Another feature related to null-
safety, unsafe call, is used in 339 out of 387 (87%) applications. As
the opposite of safe calls, the usage unsafe calls could result in
NullPointerException (NPE). We investigated some instances of this
feature manually, and we found cases where it could be substituted
by a safe call or the Elvis operator.
Finding 1:
We found a median of 16 occurrences of unsafe calls
per application, which makes these applications more prone
to ‘NullPointerException’. However, we found that occurrences
could be replaced by Kotlin’s built-in functions such as Elvis
operator to avoid NPEs.
Considering companion objects, the sixth most used feature, found
in 337 out of 387 (87%) applications, we observed that 48% of the
object declared are companion object. Companion objects are the
substitute of Java static members in Kotlin, but by default, prop-
erties and methods of companion objects are not static. To make
them static, developers should use the annotation @JvmField or
@JvmStatic, and we found several not annotated objects in our
study.
As Figure 2 shows, function with arguments with a default value
and function calls with named arguments are used in more than
60% applications of our dataset with a median of occurrences of 3
and 2 occurrences per application respectively. We normalized the
number of instances by the number of named function plus number
of constructors and the number of function calls, respectively, as
Figure 3 shows.
Finding 2:
According to the Kotlin convention, the use of
named arguments can improve the readability of the code [
23
].
However, we found that less than 1% of function calls have a
named argument.
Moreover, we found that 252 out of 387 (65%) applications that
use data classes, with a median of 1 instance per application. In
total, we found that only the 4% of applications’ classes are data
classes. Figure 3 shows the distribution of that proportion: for 25%
of applications, the proportion of data classes is more than 10% of
the total number of classes.
Kotlin provides simple approaches to use two well-known design
patterns, Singleton and Delegation. Regarding the usage of singleton,
we observed 276 out of 387 (71%) applications have at least one class
that implements Singleton pattern. Furthermore, an application has
a median 2 occurrence of this feature.
Considering properties delegation, we observed it in 210 out of
387 (54%) applications. Normalizing the number of properties dele-
gated by the number of properties for each application we found
that:
Finding 3:
Although Kotlin standard library provides for sev-
eral useful kinds of delegation, such as lazy and observable,
less than 1% of properties dened in Kotlin applications are
delegated.
Coroutine is most used feature considering those released after
Kotlin 1.0. Note that coroutine was released as an experimental
feature in Kotlin 1.1 and it was made stable in Kotlin 1.3 in October
On the adoption, usage and evolution of Kotlin features in Android development ESEM ’20, October 8–9, 2020, Bari, Italy
Figure 4: Distributions of the number of days between the
rst Kotlin commit and the commit that introduces the rst
instance of a feature.
of 2019. Comparing with type alias, also released in Kotlin 1.1,
coroutines are found in 23% of applications, whereas type aliases
are found in 13%. Since in Java, the concept of type alias does
not exist, type alias is not interoperable with Java. Therefore, this
could be one possible reason for this level of adoption. On the
other hand, coroutine might be used to perform dierent actions
concurrently without block Android’s main thread. For instance,
one could replace AsyncTaks usage by coroutine since AsyncTask
was marked as deprecated [13].
Delegation has been proven to be an alternative to inheritance
[
16
], but we found that super delegation was used only in 39 out of
387 (10%) applications. Moreover, we observed that Kotlin applica-
tions have a median of 0 occurrences of super delegation. Therefore,
we believe that the fact of inheritance is essentially absent in mobile
applications [32] can explain this nding.
Among the least used features, we found two features released
in Kotlin 1.3. Although contract was released as an experimental
feature, we found one application using it and inline class was
found in 4 applications. The same number of applications that use
tail-recursive functions, that was released in Kotlin 1.0.
Finding 4:
Less than 35% of Android apps have instances of
features like, inline function, inline class and tail-recursive
function, that might improve their performance [2, 3, 5].
Response to RQ 1: Which Kotlin features are adopted by An-
droid developers?
We studied 26 Kotlin features, and as a result, we found that
Android developers use all features of them. We identied
three groups of features: i) 7 features used in at least 80% of
applications; ii) 9 features used in more than 48% and less
than 80% of applications; iii) 10 used in less than 33%.
Furthermore, we found that type inference, lambdas and safe
calls are the most used features, being found on 98%, 95%
and 89% of applications, respectively.
4.2 RQ2: When do Android developers
introduce Kotlin features during
applications’ evolution?
To answer this research question, we used a metric dened in
Section 3.2.4, named introduction moment. Figure 4 displays its
distribution. We found that:
Finding 5:
In the following ten days after the rst commit
with Kotlin code, 15 out of 26 features are added into Android
applications.
However, comparing the introduction moment of the most and
the least used features, it turned out distinct behaviors. We found
that the most used features, type inference, lambda, safe call, when
expressions, companion object, unsafe call, string template and single-
ton, presented in median the introduction moment smaller than 1.
While the least used features presented a high introduction moment.
Finding 6:
The least used Kotlin features tend to be introduced
later on the applications’ history when compared with the most
used features.
Furthermore, the two features with the highest introduction mo-
ment, respectively, 308 and 439, were inline class and contract, both
released in Kotlin 1.3. These features were made available more
recently compared to the others. This can explain the highest intro-
duction moment. Among features released in Kotlin 1.1, we noted
that coroutine, released initially as an experimental feature, pre-
sented a smaller introduction moment than type alias. We analyzed
the date of the commits that introduced coroutine and we found
that for 87 out of 90 applications (96%) added coroutines when it was
still an experimental feature. Contract, found in one application,
it is another experimental feature used by developers. Therefore,
as found by Dyer et al. [
14
] in their study about the usage of Java
features, we observed that developers start adopting features early
when they are experimental.
Response to RQ 2: When do Android developers introduce
Kotlin features during applications’ evolution? Most features,
15 out of 26, are added into the rst days of development
using Kotlin. Moreover, while the most used Kotlin features
type inference, lambda, safe call, when expressions, companion
object and string template tend to be introduced in the rst
commit with Kotlin code, the least used features tend to be
introduced later into an application.
4.3 RQ3: How the usage of Kotlin features
evolves along with the evolution of
Android applications?
Table 2 presents the results of this research question obtained using
the methodology presented in Section 3.3.4. Each cell shows the
number and the percentage of applications whose the evolution of
a feature
f
(a row) is better described by trend
t
(a column). Addi-
tionally, the number of applications analyzed that have a feature
f
is displayed in the column Total applications.
ESEM ’20, October 8–9, 2020, Bari, Italy Bruno Gois Mateus and Matias Martinez
For 11 out of 26 (42%) features studied are better described by CR,
a constant rise trend. Moreover, 7 out of 26 (6%) features are better
described by PSR. Other 6 features (23%) presented the behavior of
stability intervals separated by a gradual rise (trend PGR Figure 1(i)).
We also observed that 2 (7%) features better described by PSD. Note
that the feature tail-recursive function is better described by two
trends, PSR and PSD. Additionally, the PGR trend better describes 1
feature (3%), inline class. Finally, we did not nd any feature better
described by stability.
Finding 7:
In general, the number of instances of features
tends to grow along with the applications’ evolution.
In Table 2, the column
Inc
shows the total number of applica-
tions and the percentage of applications which are better described
by any trend whose the number of instances increases along the
application’s evolution (i.e., CR, SR, SRP, PGR, PSR). Analogously,
the column
Dec
, shows the sum of CD, SD, PGD, PSD. Furthermore,
column
I
represents the Instability trend. Consequently, 100% of
applications are represented by columns I, Inc and Dec.
Now we explain our results for the three most used Kotlin fea-
tures , type inference, lambda, and safe call. We found that the major-
ity of applications presented a behavior of increasing the number
of instances along the applications’ evolution. Table 2 shows this
behavior in 72% of applications containing type inference, 79% of
applications containing lambda and 79% of applications containing
safe calls. Moreover, the constant rise trend, CR, better described
the evolution of these features in 36%, 36% and 30% of applications,
respectively. Considering the usage of type inference, we found
91 (26%) applications whose number of instances varies between
increase and decrease intervals along with applications’ evolution.
Furthermore, we observed only 8 (2%) applications whose number
of type inference instances decreases during applications’ evolution.
Response to RQ 3: How the usage of Kotlin features evolves
along with the evolution of Android applications? Developers
tend to add more instances along the evolution of Android
applications of 24 out of 26 (92%) features studied.
Finally, as we described in Section 3.3, to identify the trend that
better describes the evolution trend of a feature, we used R-squared,
which measures how close the data are to the tted formula. The
R-squared assumes values between 0 and 1, and 1 means a perfect
tting. In our experiment, the median R-squared was 0.88, which
means that 50% of the selected formulas describe almost perfectly
the evolution trends. Moreover, we found that 75% of evolution
trends tted presented an R-squared greater than 0.74, and only
outliers have R-squared values lower than 0.43.
4.4 Implications
As a consequence of our study, we dened several implications that
we group according to the needs of researchers, tool builders, and
software developers.
4.4.1 Researchers.
The ndings from RQ1 reveal some novel research opportunities:
Lambda is the second most used feature and with a median of 71
instances per application. This nding reveals that Android devel-
opers rely on lambda to build their applications. Mazinanian et al
.
[31]
studied the usage of lambda in Java and found several misuse
cases. Therefore, one could perform a similar study considering the
use of lambda in Kotlin. Another possibility is to investigate how
dierent is the usage of lambda in mobile applications compared
with non-mobile applications written in Java and Kotlin.
Safe call and Unsafe call are used in the majority applications
written in Kotlin. While safe call can protect applications of Null-
PointerException (NPE), unsafe call makes them more vulnerable.
The study performed by Coelho et al
. [10]
have shown that consid-
ering uncaught exceptions caused by errors in programming logic
in Android applications, the NPE is the most commom exception.
Therefore, researchers can further explore if the usage of safe call
prevents the occurrence of these exceptions eectively and, on the
contrary, if the usage unsafe call impact negatively.
4.4.2 Tool builders and IDE designers.
Android developers rely on lambdas expressions, which might result
in a more concise code when compared with the approach that uses
inner classes. However, a large number of instances can result
in overuse. Therefore, IDE can warn developers about overused
lambda, for instance, when a high number of lambdas are nested.
We found a median of 16 occurrences of unsafe calls per appli-
cation that includes some situations where developers could use
Kotlin’s built-in functions instead. Considering that, removing un-
necessary instances of unsafe calls could improve the null-safety of
Android applications, automated code assistance could suggest this
type of refactoring.
RQ1 highlights that less than 35% of Android applications have
instances of inline function, inline class and tail recursive, although
accurate use of them could improve applications’ performance.
Therefore, IDEs could detect refactoring scenarios and recommend
more ecient implementations.
4.4.3 Developers.
Regarding the use of named arguments, we consider that developers
could write a more idiomatic code following the Kotlin conventions
that suggest the use of named argument when a method takes
multiples parameters of the same primitive type or for parameters of
Boolean type [
23
]. IDEs could identify spots where name d argument
could be applied in order to follow the Kotlin conventions. On
the contrary, we noted that Android Studio renders the name of
arguments in functions calls when they are not provided, resulting
in more readable code. However, when someone tries to read that
code outside the IDEs, for instance, to perform a code review on
GitHub, the readability is not the same as in the IDE.
We observed that less than 1% of properties dened in Kotlin
applications are delegated. Inspecting the applications’ code, we
found opportunities to use property delegation to make a more
concise code. As suggested in the ocial Android development
documentation, property delegation could save development time
in some scenarios [
11
]. Better tutorials and training material could
help to promote this feature.
In RQ2, we found that most features are added into applications
in the following ten days after the rst commit with Kotlin code.
As pointed by Tufano et al
. [42]
, most of the times code artifacts
On the adoption, usage and evolution of Kotlin features in Android development ESEM ’20, October 8–9, 2020, Bari, Italy
Table 2: This table shows for each Kotlin feature X (rows) and for each evolution formula f (columns) the number of applica-
tions where the formula f better describes the evolution of the feature X . The last row, Total, shows how many features were
better described by a trend (column)
.
Features
Trends
CR CD S SR SD SRP PGR PGD PSR PSD I Inc Dec Total
Type Inference 128 (36%) 3 (1%) 0 (0%) 60 (17%) 1 (0%) 53 (15%) 10 (3%) 0 (0%) 5 (1%) 4 (1%) 91 (26%) 256 (72%) 8 (2%) 355
Lambda 124 (36%) 2 (1%) 0 (0%) 67 (20%) 4 (1%) 31 (9%) 36 (10%) 0 (0%) 14 (4%) 4 (1%) 61 (18%) 272 (79%) 10 (3%) 343
Safe Call 94 (30%) 2 (1%) 0 (0%) 64 (20%) 3 (1%) 38 (12%) 33 (10%) 1 (0%) 21 (7%) 9 (3%) 51 (16%) 250 (79%) 15 (5%) 316
When Expr 85 (29%) 3 (1%) 0 (0%) 47 (16%) 2 (1%) 28 (10%) 72 (24%) 0 (0%) 29 (10%) 5 (2%) 23 (8%) 261 (89%) 10 (3%) 294
Unsafe Call 60 (19%) 32 (10%) 0 (0%) 54 (17%) 19 (6%) 25 (8%) 41 (13%) 3 (1%) 17 (5%) 11 (4%) 51 (16%) 197 (63%) 65 (21%) 313
Companion Object 75 (26%) 11 (4%) 0 (0%) 38 (13%) 8 (3%) 33 (11%) 57 (20%) 2 (1%) 39 (13%) 5 (2%) 22 (8%) 242 (83%) 26 (9%) 290
String Template 80 (27%) 5 (2%) 0 (0%) 39 (13%) 6 (2%) 32 (11%) 59 (20%) 1 (0%) 28 (9%) 7 (2%) 38 (13%) 238 (81%) 19 (6%) 295
Func With Default Value 50 (21%) 3 (1%) 0 (0%) 41 (18%) 4 (2%) 19 (8%) 64 (27%) 3 (1%) 27 (12%) 6 (3%) 17 (7%) 201 (86%) 16 (7%) 234
Singleton 33 (15%) 6 (3%) 0 (0%) 36 (16%) 7 (3%) 25 (11%) 51 (22%) 3 (1%) 29 (13%) 24 (11%) 13 (6%) 174 (77%) 40 (18%) 227
Range Expr 30 (14%) 14 (7%) 0 (0%) 28 (13%) 5 (2%) 17 (8%) 47 (22%) 6 (3%) 38 (18%) 14 (7%) 12 (6%) 160 (76%) 39 (18%) 211
Smart Cast 38 (18%) 14 (7%) 0 (0%) 35 (17%) 8 (4%) 20 (10%) 40 (19%) 4 (2%) 25 (12%) 14 (7%) 10 (5%) 158 (76%) 40 (19%) 208
Data Class 44 (22%) 2 (1%) 0 (0%) 28 (14%) 5 (2%) 19 (9%) 51 (25%) 0 (0%) 35 (17%) 6 (3%) 14 (7%) 177 (87%) 13 (6%) 204
Func Call With Named Arg 48 (22%) 2 (1%) 0 (0%) 40 (19%) 6 (3%) 20 (9%) 41 (19%) 1 (0%) 30 (14%) 8 (4%) 19 (9%) 179 (83%) 17 (8%) 215
Extension Function 47 (23%) 4 (2%) 0 (0%) 32 (16%) 7 (3%) 23 (11%) 42 (21%) 1 (0%) 22 (11%) 7 (3%) 16 (8%) 166 (83%) 19 (9%) 201
Property Delegation 40 (22%) 11 (6%) 0 (0%) 32 (18%) 8 (4%) 22 (12%) 23 (13%) 3 (2%) 18 (10%) 5 (3%) 17 (9%) 135 (75%) 27 (15%) 179
Destructuring Declaration 23 (16%) 9 (6%) 0 (0%) 14 (10%) 5 (3%) 9 (6%) 33 (23%) 4 (3%) 25 (17%) 16 (11%) 5 (3%) 104 (73%) 34 (24%) 143
Inline Func 11 (12%) 5 (5%) 0 (0%) 11 (12%) 5 (5%) 5 (5%) 17 (18%) 2 (2%) 20 (21%) 14 (15%) 5 (5%) 64 (67%) 26 (27%) 95
Overloaded Op 9 (14%) 3 (5%) 0 (0%) 5 (8%) 2 (3%) 5 (8%) 11 (17%) 2 (3%) 15 (23%) 11 (17%) 1 (2%) 45 (70%) 18 (28%) 64
Coroutine 17 (22%) 1 (1%) 0 (0%) 12 (16%) 1 (1%) 8 (11%) 16 (21%) 0 (0%) 6 (8%) 1 (1%) 14 (18%) 59 (78%) 3 (4%) 76
Sealed Class 6 (9%) 3 (5%) 0 (0%) 10 (15%) 1 (2%) 5 (8%) 7 (11%) 0 (0%) 26 (40%) 3 (5%) 4 (6%) 54 (83%) 7 (11%) 65
Type Alias 2 (7%) 1 (3%) 0 (0%) 6 (20%) 1 (3%) 0 (0%) 8 (27%) 0 (0%) 10 (33%) 2 (7%) 0 (0%) 26 (87%) 4 (13%) 30
Super Delegation 3 (10%) 0 (0%) 0 (0%) 1 (3%) 3 (10%) 4 (14%) 3 (10%) 0 (0%) 10 (34%) 4 (14%) 1 (3%) 21 (72%) 7 (24%) 29
Inx Func 3 (19%) 0 (0%) 0 (0%) 0 (0%) 1 (6%) 0 (0%) 3 (19%) 0 (0%) 3 (19%) 6 (38%) 0 (0%) 9 (56%) 7 (44%) 16
Inline Klass 0 (0%) 0 (0%) 0 (0%) 0 (0%) 0 (0%) 1 (100%) 0 (0%) 0 (0%) 0 (0%) 0 (0%) 0 (0%) 1 (100%) 0 (0%) 1
Tailrec Func 0 (0%) 0 (0%) 0 (0%) 0 (0%) 0 (0%) 0 (0%) 0 (0%) 0 (0%) 1 (50%) 1 (50%) 0 (0%) 1 (50%) 1 (50%) 2
Contract 0 (0%) 0 (0%) 0 (0%) 0 (0%) 0 (0%) 0 (0%) 0 (0%) 0 (0%) 1 (100%) 0 (0%) 0 (0%) 1 (100%) 0 (0%) 1
Total 11 0 0 0 0 1 6 0 7 2 0 - - -
are aected by bad smells since their creation. Therefore, a solid
understanding of these features would help developers to use them
correctly since the initial phase of development, potentially improv-
ing the code quality. A dedicated training focused on these features
would especially help novice Kotlin developers. On the contrary,
the least used Kotlin features tend to be introduced later than the
most used features. A possible reason is that developers need more
experience with Kotlin to start using these features. Then, promot-
ing these features could help developers to identify opportunities
for using them in the early days of development.
We observed that developers add more instances along with the
applications’ evolution. As the number of instances grows, appli-
cations become more prone to overusing of features. Continuous
integration and static analyzers could be used to track the use of
features and to identify misuse and anti-patterns.
5 THREATS TO VALIDITY
5.1 Internal
Selection of features. We investigated the adoption and usage evo-
lution of a subset of Kotlin features not available in Java. As the
criterion used to select the targeted features impact our results,
we consider the ones listed in the ocial Kotlin documentation to
avoid any bias [1].
Feature identication. Our results depend on how precisely we
identify the target features. Due to the absence of a benchmark of
the use of Kotlin features, To evaluate our tool, we manually ana-
lyzed 96 instances of each feature and we found 100% of precision.
Evolution trend identication. One of the goals of our work is
to identify evolution trends. To avoid any bias, we established 11
evolution trends (See Section 3.3.3) similarly used in other stud-
ies [
19
,
22
,
26
]. Moreover, to match a feature evolution with one
of the studied trends, we dened 6 formulas. However, it is possi-
ble that other formulas, not used in this paper, t better with any
evolution trend.
5.2 External
Representativeness of FAMAZOA. Our work relies on FAMAZOA [
19
],
a dataset of open-source mobile applications written in Kotlin.
Considering the number of applications published on Google Play,
FAMAZOA represents a small parcel since it only contains open-
source applications, limiting the generalization of our ndings.
However, to the best of our knowledge, it is the largest dataset of
Android open-source applications written in Kotlin.
Developer’s experience. In our work, we analyzed the source code
of dierent Android applications. The use of some studied features
may require more experience from developers to be used properly.
However, we did not consider information about developers’ ex-
perience. Nevertheless, all applications analyzed were published
on F-droid or Google Play, then it represents a current snapshot
of Android development. We will consider this aspect in a future
work.
ESEM ’20, October 8–9, 2020, Bari, Italy Bruno Gois Mateus and Matias Martinez
6 RELATED WORK
We group the related work into three areas: 1) studies on adoption
of language features 2) studies on the usage evolution of language
features and 3) evolution of Android applications.
Studies on adoption of language features. Several empirical studies
about features of dierent programming languages have been done.
Sutton et al
. [41]
developed a tool to identify the use of generic
libraries in C++ projects to support a programmer’s comprehension.
Parnin et al
. [36
,
37]
conducted an empirical study to understand
how Java generics have been integrated into open-source software
by mining repositories of 40 popular Java programs. They found
that one or two contributors often adopt generics and generics can
reduce the number of typecasts in a project. Uesbeck et al
. [43]
investigated the impact of lambda expressions on the development,
debugging, and testing eort in C++. Pinto et al
. [38]
studied the
energy eciency of Java’s Thread-Safe Collections and concluded
that simple design decisions could impact energy consumption.
Chapman and Stolee
[9]
studied the usage of regular expressions
in Python conducting an empirical study of open-source projects
from GitHub. They found six common behaviors that describe
how regular expressions are often used in practice. JavaScript fea-
tures were also the target of studies. Silva et al
. [40]
developed a
tool to investigate how class emulation is employed in JavaScript
applications. They observed that 26% of 50 most popular applica-
tions from Github do not use class. Gallaba et al
. [17]
focused on
the usage of asynchronous callbacks in JavaScript. They evaluated
their tool, PROMISESLAND, and found that it substitutes callbacks
to promises (an alternative to asynchronous callbacks), correctly.
Moreover, none of them has studied the features of Kotlin.
Studies on the usage evolution of language features. Various stud-
ies on the adoption of features over time have been done. Pinto
et al
. [39]
and Wu et al
. [44]
performed large empirical studies to
investigate the usage of concurrency constructs in open-source
applications in Java and C++, respectively. Pinto et al
. [39]
found
more than 75% of 2227 projects either explicitly create threads or
employ some concurrency control mechanism. Wu et al
. [44]
found
that small-size applications introduce concurrency constructs more
intensively and quicker than medium-size applications and large-
size applications. Osman et al
. [34
,
35]
conducted empirical studies
on long-lived Java systems and observed that the amount of error-
handling code, the number of custom exceptions and their usage in
catch handlers and throw statements increase as projects evolve. Yu
et al
. [46]
conducted an empirical study to evaluate the usage, evo-
lution and impact of Java Annotations. Malloy and Power [27, 28]
investigated the degree to which Python developers are migrating
from Python 2 to 3 by measuring the adoption of Python 3 features.
They found that developers were choosing to maintain backward
compatibility with Python 2 instead of exploiting the new features
and advantages of Python 3. To identify the uses over time of new
features of Java, Dyer et al
. [15]
analyzed 23,000 open-source Java
projects. They observed that all features are used even before their
release date and that there were still millions of opportunities for
use. Mazinanian et al
. [31]
focused on the evolution trend of one
Java feature, Lambdas. They conducted an empirical study, statically
analyzing the source code of 241 open-source projects and inter-
viewing 97 developers who introduced lambdas in their projects.
As a result, they revealed an increasing trend in the adoption of
lambdas. In contrast with the previous studies, our work focuses
on a set of Kotlin features, their adoption and evolution along with
applications’ version.
Evolution of Android applications. Several aspects of the evolution
of Android applications were investigated in the literature. Hecht
et al
. [22]
presented an approach for performing static code analysis
on Android applications’ bytecode to detect code smells and they
identied ve dierent quality evolution trends. Calciati and Gorla
[7]
investigated the evolution of permission requests analyzing
more than 14,000 applications. They found that applications tend
increase the number permissions needed over time. Góis Mateus
and Martinez
[19]
conducted the rst empirical study about Android
applications written in Kotlin. Analyzing the source code of Android
applications they identied 12 evolution trends. Malavolta et al
. [26]
investigated the evolution of 6 maintainability issues along with
the evolution of Android applications. Inspecting the density of
maintainability issues, they identied 12 dierent evolution trends
and concluded that independently from the type of development
activity and notwithstanding the issue type, maintainability issue
density grows until it stabilizes. Habchi et al
. [21]
presented the rst
large-scale empirical study that investigates the survival of eight
types of Android code smells. They reported that while in terms
of time Android code smells can remain in the codebase for years
before being removed, it only takes 34 eective commits to remove
75% of them. Calciati et al
. [8]
proposed a framework to analyze
the evolution of Android applications. Analyzing 235 applications
with at least 50 releases, they found that Android applications tend
to have more leaks of sensitive data over time. These studies tie
into our research because they focus on the evolution of Android
applications. Our study applied a methodology similar to [
19
,
22
,
26
]
to identify evolution trends of feature usage. However, these studies
used a manual approach to classify the identied trends. Dierently,
in our work, we applied an automated classication approach. To
the best of our knowledge, this work is the rst empirical study
about the adoption and evolution of Kotlin features.
7 CONCLUSION
We conducted the rst empirical study exploring dierent aspects
of the adoption and evolution of Kotlin features not available in
Java for Android development. We extracted 26 features from ap-
plications’ source code and we identied when they were used for
the rst time. To classify the evolution trends of these features, we
rst dened 11 evolution trends modeled by 5 functions. Then, we
created an automated method of classication. We found that 15
out of 26 features are used by the majority of Android applications.
Typ e inference, lambda and safe call are the most used features, they
are presented in 98%, 95% and 89% of applications, respectively.
Furthermore, we observed that the most used features are added in
the rst Kotlin commit, and the least used features are introduced
in the latest commits. Finally, we found that 24 out of 26 features
presented an increasing of features instances along with the applica-
tions’ evolution. As future work, we intent to perform a qualitative
study that interviews developers focused on understanding the
motivation behind the use of Kotlin features to complement this
work.
On the adoption, usage and evolution of Kotlin features in Android development ESEM ’20, October 8–9, 2020, Bari, Italy
REFERENCES
[1]
2016. Comparison to Java Programming Language. https://kotlinlang.org/docs/
reference/comparison-to-java.html Online; accessed 01-July-2019.
[2]
2016. Inline Classes. https://kotlinlang.org/docs/reference/functions.html#tail-
recursive-functions Online; accessed 01-July-2019.
[3]
2016. Inline Functions. https://kotlinlang.org/docs/reference/inline-functions.
html Online; accessed 01-July-2019.
[4]
2017. Will "It" variable stay or go? https://discuss.kotlinlang.org/t/will-it-
variable-stay-or-go/522/19 Online; accessed 01-July-2019.
[5]
2018. Inline Classes. https://kotlinlang.org/docs/reference/inline-classes.html
Online; accessed 01-July-2019.
[6]
Kevin Allix, Tegawendé F. Bissyandé, Jacques Klein, and Yves Le Traon. 2016. An-
droZoo: Collecting Millions of Android Apps for the Research Community Kevin.
Proceedings of the 13th International Workshop on Mining Software Repositories -
MSR ’16 (2016), 468–471. https://doi.org/10.1145/2901739.2903508
[7]
Paolo Calciati and Alessandra Gorla. 2017. How Do Apps Evolve in Their Per-
mission Requests?: A Preliminary Study. In Proceedings of the 14th International
Conference on Mining Software Repositories (Buenos Aires, Argentina) (MSR ’17).
IEEE Press, Piscataway, NJ, USA, 37–41. https://doi.org/10.1109/MSR.2017.64
[8]
Paolo Calciati, Konstantin Kuznetsov, Xue Bai, and Alessandra Gorla. 2018. What
Did Really Change with the New Release of the App?. In Proceedings of the 15th
International Conference on Mining Software Repositories (Gothenburg, Sweden)
(MSR ’18). ACM, New York, NY, USA, 142–152. https://doi.org/10.1145/3196398.
3196449
[9]
Carl Chapman and Kathryn T. Stolee. 2016. Exploring Regular Expression Usage
and Context in Python. In Proceedings of the 25th International Symposium on
Software Testing and Analysis (Saarbrücken, Germany) (ISSTA 2016). ACM, New
York, NY, USA, 282–293. https://doi.org/10.1145/2931037.2931073
[10]
Roberta Coelho, Lucas Almeida, Georgios Gousios, and Arie van Deursen. 2015.
Unveiling Exception Handling Bug Hazards in Android Based on GitHub and
Google Code Issues. In Proceedings of the 12th Working Conference on Mining
Software Repositories (Florence, Italy) (MSR ’15). IEEE Press, 134–145.
[11]
Android Developers. [n.d.]. Use common Kotlin patterns with Android. https:
//developer.android.com/kotlin/common-patterns#delegate Online; accessed
01-July-2019.
[12]
Android Developers. 2017. Use Java 8 language features. https://developer.
android.com/studio/write/java8-support Online; accessed 01-July-2019.
[13]
Android Developers. 2019. AsyncTask API Reference. https://developer.android.
com/reference/android/os/AsyncTask/ [Online; accessed 3-December-2019].
[14]
Robert Dyer. 2013. A Large-scale Empirical Study of Java Language Feature Usage.
Technical Report. Iowa State University.
[15]
Robert Dyer, Hridesh Rajan, Hoan Anh Nguyen, and Tien N. Nguyen. 2014.
Mining Billions of AST Nodes to Study Actual and Potential Usage of Java
Language Features. In Proceedings of the 36th International Conference on Software
Engineering (Hyderabad, India) (ICSE 2014). ACM, New York, NY, USA, 779–790.
https://doi.org/10.1145/2568225.2568295
[16]
Martin Fowler. 2018. Refactoring: improving the design of existing code. Addison-
Wesley Professional.
[17]
Keheliya Gallaba, Quinn Hanam, Ali Mesbah, and Ivan Beschastnikh. 2017. Refac-
toring asynchrony in JavaScript. In 2017 IEEE International Conference on Software
Maintenance and Evolution (ICSME). IEEE, IEEE, 353–363.
[18]
Franz-Xaver Geiger, Ivano Malavolta, Luca Pascarella, Fabio Palomba, Dario
Di Nucci, and Alberto Bacchelli. 2018. A Graph-based Dataset of Commit History
of Real-world Android Apps. In Proceedings of the 15th International Conference
on Mining Software Repositories (Gothenburg, Sweden) (MSR ’18). ACM, New
York, NY, USA, 30–33. https://doi.org/10.1145/3196398.3196460
[19]
Bruno Góis Mateus and Matias Martinez. 2019. An empirical study on quality of
Android applications written in Kotlin language. Empirical Software Engineering
24, 6 (01 Dec 2019), 3356–3393. https://doi.org/10.1007/s10664-019-09727-4
[20]
Chet Haase. 2019. Google I/O 2019: Empowering developers to
build the best experiences on Android Play. https://android-
developers.googleblog.com/2019/05/google-io-2019-empowering-developers-
to-build-experiences-on-Android-Play.html Online; accessed 21-April-2020.
[21]
Sarra Habchi, Romain Rouvoy, and Naouel Moha. 2019. On the Survival of
Android Code Smells in the Wild. In Proceedings of the 6th International Confer-
ence on Mobile Software Engineering and Systems (Montreal, Quebec, Canada)
(MOBILESoft ’19). IEEE Press, 87–98.
[22]
Georey Hecht, Omar Benomar, Romain Rouvoy, Naouel Moha, and Laurence
Duchien. 2015. Tracking the Software Quality of Android Applications Along
Their Evolution. In Proceedings of the 2015 30th IEEE/ACM International Conference
on Automated Software Engineering (ASE) (ASE ’15). IEEE Computer Society,
Washington, DC, USA, 236–247. https://doi.org/10.1109/ASE.2015.46
[23]
JetBrains. 2019. Kotlin Coding Conventions.
https://kotlinlang.org/docs/reference/coding-conventions.html.
[24]
JetBrains. 2019. Kotlin Language Documentation.
https://kotlinlang.org/docs/kotlin-docs.pdf.
[25]
Eric Jones, Travis Oliphant, Pearu Peterson, et al
.
2001–. SciPy: Open source
scientic tools for Python. http://www.scipy.org/ [Online; accessed 21-April-
2020].
[26]
I. Malavolta, R. Verdecchia, B. Filipovic, M. Bruntink, and P. Lago. 2018. How
Maintainability Issues of Android Apps Evolve. In 2018 IEEE International
Conference on Software Maintenance and Evolution (ICSME). 334–344. https:
//doi.org/10.1109/ICSME.2018.00042
[27]
B. A. Malloy and J. F. Power. 2017. Quantifying the Transition from Python 2 to
3: An Empirical Study of Python Applications. In 2017 ACM/IEEE International
Symposium on Empirical Software Engineering and Measurement (ESEM). 314–323.
https://doi.org/10.1109/ESEM.2017.45
[28]
Brian A. Malloy and James F. Power. 2019. An empirical analysis of the transition
from Python 2 to Python 3. Empirical Software Engineering 24, 2 (01 Apr 2019),
751–778. https://doi.org/10.1007/s10664-018-9637-2
[29]
Matias Martinez and Bruno Gois Mateus. 2020. How and Why did developers
migrate Android Applications from Java to Kotlin? A study based on code analysis
and interviews with developers. https://arxiv.org/pdf/2003.12730.pdf. (2020).
arXiv:2003.12730
[30]
Matias Martinez and Martin Monperrus. 2019. Coming: A Tool for Mining Change
Pattern Instances from Git Commits. In Proceedings of the 41st International
Conference on Software Engineering: Companion Proceedings (Montreal, Quebec,
Canada) (ICSE ’19). IEEE Press, 79–82. https://doi.org/10.1109/ICSE-Companion.
2019.00043
[31]
Davood Mazinanian, Ameya Ketkar, Nikolaos Tsantalis, and Danny Dig. 2017.
Understanding the Use of Lambda Expressions in Java. Proc. ACM Program. Lang.
1, OOPSLA, Article 85 (Oct. 2017), 31 pages. https://doi.org/10.1145/3133909
[32]
Roberto Minelli and Michele Lanza. 2013. Software analytics for mobile ap-
plications - Insights & lessons learned. Proceedings of the European Confer-
ence on Software Maintenance and Reengineering, CSMR (2013), 144–153. https:
//doi.org/10.1109/CSMR.2013.24
[33]
V. Oliveira, L. Teixeira, and F. Ebert. 2020. On the Adoption of Kotlin on Android
Development: A Triangulation Study. In 2020 IEEE 27th International Conference
on Software Analysis, Evolution and Reengineering (SANER). IEEE, 206–216.
[34]
H. Osman, A. Chis, C. Corrodi, M. Ghafari, and O. Nierstrasz. 2017. Exception
Evolution in Long-Lived Java Systems. In 2017 IEEE/ACM 14th International
Conference on Mining Software Repositories (MSR). 302–311. https://doi.org/10.
1109/MSR.2017.21
[35]
H. Osman, A. Chiş, J. Schaerer, M. Ghafari, and O. Nierstrasz. 2017. On the
evolution of exception usage in Java projects. In 2017 IEEE 24th International
Conference on Software Analysis, Evolution and Reengine ering (SANER). IEEE,
422–426. https://doi.org/10.1109/SANER.2017.7884646
[36]
Chris Parnin, Christian Bird, and Emerson Murphy-Hill. 2011. Java
Generics Adoption: How New Features are Introduced, Champi-
oned, or Ignored. In Proceedings of the International Working Con-
ference on Mining Software Repositories (proceedings of the interna-
tional working conference on mining software repositories ed.). ACM.
https://www.microsoft.com/en-us/research/publication/java-generics-
adoption-how-new-features-are-introduced-championed-or-ignored/
[37]
Chris Parnin, Christian Bird, and Emerson Murphy-Hill. 2013. Adoption and use
of Java generics. Empirical Software Engineering 18, 6 (01 Dec 2013), 1047–1089.
https://doi.org/10.1007/s10664-012-9236-6
[38]
G. Pinto, K. Liu, F. Castor, and Y. D. Liu. 2016. A Comprehensive Study on the
Energy Eciency of Java’s Thread-Safe Collections. In 2016 IEEE International
Conference on Software Maintenance and Evolution (ICSME). 20–31. https://doi.
org/10.1109/ICSME.2016.34
[39]
Gustavo Pinto, Weslley Torres, Benito Fernandes, Fernando Castor, and
Roberto S.M. Barros. 2015. A Large-scale Study on the Usage of Java’s Con-
current Programming Constructs. J. Syst. Softw. 106, C (Aug. 2015), 59–81.
https://doi.org/10.1016/j.jss.2015.04.064
[40]
Leonardo Humberto Silva, Miguel Ramos, Marco Tulio Valente, Alexandre Bergel,
and Nicolas Anquetil. 2015. Does JavaScript software embrace classes?. In 2015
IEEE 22nd International Conference on Software Analysis, Evolution, and Reengi-
neering (SANER). IEEE, 73–82.
[41]
Andrew Sutton, Ryan Holeman, and Jonathan I. Maletic. 2010. Identication
of Idiom Usage in C++ Generic Libraries. In Proceedings of the 2010 IEEE 18th
International Conference on Program Comprehension (ICPC ’10). IEEE Computer
Society, USA, 160–169. https://doi.org/10.1109/ICPC.2010.37
[42]
Michele Tufano, Fabio Palomba, Gabriele Bavota, Rocco Olivetox, Massimiliano Di
Penta, Andrea De Lucia, and Denys Poshyvanyk. 2015. When and why your code
starts to smell bad. Icse 1 (2015), 403–414. https://doi.org/10.1109/ICSE.2015.59
[43]
Phillip Merlin Uesbeck, Andreas Stek, Stefan Hanenberg, Jan Pedersen, and
Patrick Daleiden. 2016. An Empirical Study on the Impact of C++ Lambdas
and Programmer Experience. In Proceedings of the 38th International Conference
on Software Engineering (Austin, Texas) (ICSE ’16). ACM, New York, NY, USA,
760–771. https://doi.org/10.1145/2884781.2884849
[44]
Di Wu, Lin Chen, Yuming Zhou, and Baowen Xu. 2016. An Extensive Empirical
Study on C++ Concurrency Constructs. Inf. Softw. Technol. 76, C (Aug. 2016),
1–18. https://doi.org/10.1016/j.infsof.2016.04.004
ESEM ’20, October 8–9, 2020, Bari, Italy Bruno Gois Mateus and Matias Martinez
[45]
Shengqian Yang, Dacong Yan, Haowei Wu, Yan Wang, and Atanas Rountev. 2015.
Static Control-Flow Analysis of User-Driven Callbacks in Android Applications.
In Proceedings of the 37th International Conference on Software Engineering -
Volume 1 (Florence, Italy) (ICSE ’15). IEEE Press, 89–99.
[46]
Zhongxing Yu, Chenggang Bai, Lionel Seinturier, and Martin Monperrus. 2019.
Characterizing the Usage, Evolution and Impact of Java Annotations in Practice.
IEEE TSE: Transactions on Software Engineering (2019). https://hal.inria.fr/hal-
02091516