Kotlin vs. Scala
The question of whether to choose Kotlin or Scala doesn’t come up often in the Android community because the Android tool support for Scala just isn’t very good, and the Scala library for Android tends to be on the large side. On the other hand, the Scala community is keenly aware of the issues and is working on solutions for them.
In other environments, the situation is different. For example, Apache Spark is mostly written in Scala, and big data applications for Spark are often written in Scala.
In many ways both Scala and Kotlin represent the fusion of object-oriented programming, as exemplified by Java, with functional programming. The two languages share many concepts and notations, such as immutable declarations using val
and mutable declarations using var
, but differ slightly on others, such as where to put the arrow when declaring a lambda function, and whether to use a single arrow or a double arrow. The Kotlin data class
maps to the Scala case class
.
Kotlin defines nullable variables in a way that is similar to Groovy, C#, and F#; most people get it quickly. Scala, on the other hand, defines nullable variables using the Option
monad, which can be so forbidding that some authors seem to think that Scala doesn’t have null safety.
One clear deficit of Scala is that its compile times tend to be long, something that is most obvious when you’re building a large body of Scala, such as the Spark repository, from source. Kotlin, on the other hand, was designed to compile quickly in the most frequent software development scenarios, and in fact often compiles faster than Java code.
Kotlin interoperability with Java
At this point you may be wondering how Kotlin handles the results of Java interoperability calls, given the differences in null
handling and checked exceptions. Kotlin silently and reliably infers what is called a “platform type” that behaves exactly like a Java type, meaning that is nullable but can generate null-pointer exceptions. Kotlin may also inject an assertion into the code at compile time to avoid triggering an actual null pointer exception. There’s no explicit language notation for a platform type, but in the event Kotlin has to report a platform type, such as in an error message, it appends !
to the type.
In most cases, calling Java code from Kotlin works the way you might expect. For example, any time both getters and setters exist in a Java class, Kotlin treats them as properties with the same name. Similarly, Boolean accessor methods are treated as properties that have the same name as the getter method. For example:
import java.util.Calendar
fun calendarDemo() {
val calendar = Calendar.getInstance()
if (calendar.firstDayOfWeek == Calendar.SUNDAY) { // call getFirstDayOfWeek()
calendar.firstDayOfWeek = Calendar.MONDAY // call setFirstDayOfWeek()
}
if (!calendar.isLenient) { // call isLenient()
calendar.isLenient = true // call setLenient()
}
}
This scheme breaks down for the case of Java set-only properties, which are not yet supported in Kotlin. If a Java class has only a setter, it will not be visible as a property in Kotlin.
Kotlin’s interoperability with Java extends to Java tools. Kotlin doesn’t have its own editors or IDEs; it has plug-ins for the popular Java editors and IDEs, including IntelliJ IDEA, Android Studio, and Eclipse. Kotlin doesn’t have its own build system; it uses Gradle, Maven, and Ant.
Kotlin interoperability with JavaScript
You can use Kotlin to write code for browsers and Node.js. With this target, Kotlin is transpiled to JavaScript ES5.1 instead of being compiled to JVM byte code.
Because JavaScript is a dynamic language, Kotlin for JavaScript adds a dynamic type not available in Kotlin for the JVM:
val dyn: dynamic = ...
The Kotlin type checker ignores dynamic
types and lets JavaScript deal with them at runtime. Expressions using values of dynamic
type are translated to JavaScript as written. Again, Kotlin basically punts and lets JavaScript interpret the expressions at runtime.
You can call JavaScript from Kotlin two ways: using dynamic
types or using strongly typed Kotlin headers for JavaScript libraries. To access well-known, third-party JavaScript frameworks with a strongly typed API, you can convert TypeScript definitions from the DefinitelyTyped type definitions repository to Kotlin using the ts2kt tool.
You can inline JavaScript code as text into your Kotlin code using the js("…")
function. You can mark package declarations in Kotlin code as pure JavaScript with the external
modifier. You can call Kotlin code from JavaScript, but you need to use fully qualified names.
Kotlin applications
Kotlin can be used for any kind of development: server-side, client-side web, Android, and native code. In a recent poll performed shortly after the release of Kotlin/Native, responses from developers who counted Kotlin among their top three programming languages indicated that 66 percent used Kotlin for Android, 57 percent Kotlin/JVM, 8 percent Kotlin/Native, and 5 percent Kotlin/JS.
Kotlin/Native developers said they targeted (in order of frequency) Linux, Android, macOS, Windows, iOS, WebAssembly, and embedded systems.
Overall, Kotlin offers several advantages over Java for code to be run on the JVM, and Kotlin can also be used to generate JavaScript and native code. Compared to Java, Kotlin is safer, more concise, and more explicit. It supports functional programming in addition to object-oriented programming, offers a bunch of useful features (extension functions, builders, coroutines, lambdas, etc.), and provides null safety through nullable and non-nullable types. Best of all, if you already know Java, you’ll be productive in Kotlin in no time.