Kotlin vs. Scala: What Should I Choose Instead of Java?
With the news that Kotlin is now an officially supported language for Android development, JetBrains’ programming language has been getting a lot of attention lately — so much so that it’s left many Java developers wondering whether they should be making the switch to Kotlin.
If you’re considering moving away from Java, however, you should know that Kotlin isn’t your only option.
In this article, we’re going to be looking at all of the major differences between Kotlin and Scala — a language that Kotlin borrows from.
We’ll be covering some of the fundamental differences between Scala and Kotlin, such as their approach to Java compatibility and the level of community support available for each language, before diving into the technical, language-level differences between the two.
By the end of this article, you’ll have all the information you need to decide whether Scala or Kotlin is the best “alternative” Java Virtual Machine (JVM) language for you.
Note: Although this article is aimed at developers who are considering moving away from Java, it also contains lots of information that’ll be useful for any Scala developers who may be wondering whether Kotlin has anything to offer them.
What are you looking for in your next programming language?
Although they’re both widely considered to be Java alternatives, Scala and Kotlin both have very different approaches to “improving” Java.
Kotlin aims to be a better Java by cutting down on boilerplate code and introducing some features that Java is sorely lacking, such as a null safe design.
In contrast, Scala is designed to be different from Java, with a flexible syntax that’s more heavily influenced by functional programming concepts. Java 8 may have introduced many functional programming features, but it’s still very much an imperative language. This makes Scala ideal for situations where you want to tap into the "write once run everywhere" portability of the JVM, while coding in a more functional style. Scala’s mixture of object-oriented and functional programming constructs also makes it a good fit for any projects where you want to combine these two programming styles.
In addition, Scala includes features that you won’t find in either Kotlin or Java, such as full support for pattern matching, macros, and higher-kinded types, which makes Scala ideal for big data processing tasks such as: graph analysis, aggregation computations, and complex, mathematically-focused modelling (e.g. medical modelling.) If you’re a data scientist who regularly deals with large datasets, then you may find Scala’s more advanced features, concurrency support and close relationship with data processing engine Apache Spark, to be invaluable.
As you’ll see throughout this article, whether Scala or Kotlin is the best choice for you largely depends on what you’re looking for: a language that aims to be a better version of Java or a language that allows you to do things that aren’t possible in Java.
You can look at this another way: why do you want to move away from Java in the first place? If you’re happy with Java in general but are frustrated by its verbosity, then Kotlin may be exactly what you’re looking for. If you’re fed up with Java’s feature set and limitations, switching to Scala might make more sense.
How easy is each language to learn?
Since Scala has many powerful, advanced features and a flexible syntax, it’s no surprise that it isn’t the easiest language to learn, and can be intimidating for newcomers.
In contrast, many Java developers who have made the switch to Kotlin praise just how easy it is to learn. Some organizations reported that their Java developers were able to pick up the basic Kolin syntax in just a few hours and started to write Kotlin code in around one to three days.
However, just because a language is easier to pick up doesn’t automatically make it better. Kotlin may be widely considered the easier language to learn, but if it doesn’t have all the features you need, then those few hours spent familiarizing yourself with the Kotlin syntax was time that you could have spent starting to learning a language that does give you the functionality you need.
Java interoperability
Switching from one language to another isn’t always a clean break — you may have legacy code that you need to continue to support or ongoing Java projects that you’d prefer not to have to immediately convert into a new language.
Both Scala and Kotlin are interoperable with Java. However, if circumstances call for you to maintain full compatibility with existing Java-based technology or projects, Kotlin has the edge, as it’s designed to be 100% interoperable with Java. You can easily call Kotlin code from Java, and Java code from Kotlin without any problems. If you want to use Kotlin for server-side development, you can use existing Java-based frameworks, such as Java Server Faces (JSF), or the reactive web application ‘Vert.x’ framework.
Although you should have no issues accessing Java classes from Scala code, you may run into problems when attempting to call Scala classes from Java if you’re using some of Scala’s more advanced features, as these often don’t have a Java equivalent.
Resources and community support
JetBrains unveiled Kotlin in 2011, and Scala made its first public appearance in 2004.
Both languages have pretty thorough documentation, but as a newer language, Kotlin has significantly fewer community resources in terms of native libraries, blog posts, and tutorials. In fact, if you search developer Q&A site Stack Overflow, you’ll only find 3.8K questions that are tagged Kotlin
, compared to over 68.5K questions tagged with Scala
.
If you do need information that isn’t included in the official docs, you may have a much harder time finding it at the moment if you choose Kotlin, rather than Scala, as your next JVM language.
Kotlin is officially supported in Android
No Kotlin article would be complete without at least mentioning the fact that Kotlin recently became an officially supported language for Android development.
If you’re looking for a new JVM language for your Android work, it’s difficult not to recommend Kotlin. In Android Studio 3.0 Preview and higher, creating a project with Kotlin support is as simple as selecting a checkbox in the project creation wizard. In addition, there are a few features that make Kotlin particularly well-suited to Android development:
Extension functions: This is where you add new functionality to an existing class. In the context of Android apps, Extension Functions are particularly useful for giving ViewGroups the ability to inflate themselves.
Kotlin Android Extensions: This feature allows you to import a reference to a View into an Activity, which has the potential to make all of that findViewById boilerplate code a thing of the past.
Although an Android SDK Plugin for SBT does exist, it’s something that you need to add to your development environment, and it isn’t officially supported by Android Studio.
Null Design vs. the Option Operator
Now we’re getting into the language-level differences. One of the biggest differences between Scala and Kotlin is how they handle null.
The vast majority of Java developers will be very familiar with NullPointerExceptions
(NPEs). Although Java 8’s @NonNull
annotation does help to alleviate some of the pain inflicted by NPEs, null remains a huge source of frustration for Java developers.
Scala takes a monadic approach to null, by replacing null values with Option
, which is Scala’s own type for representing values that may or may not exist. An Option can either contain no value (None) or a single value, which is represented as Some[value of the correct type]
.
Let’s imagine you have a method that returns an address from a database:
def findAddress(key: Int): Option[Address]
If a record is found, then this method will return Some[Address]
. If a record isn’t found, it’ll return None.
The drawback to this approach is that it does add some complexity to your code, as you need to explicitly use Option. Also, null is still present in Scala because val x: Option[Int] = null
is perfectly valid. On the plus side, you can apply other methods to your Option value, so you have more flexibility in how you handle potential None/null values.
In contrast, Kotlin refuses to compile code that assigns or returns a null value. For example, the following won’t compile:
val name: String = null
john getName() : String = null
This doesn’t add any complexity to your code and makes it almost impossible to encounter NPEs in Kotlin, although you may still encounter NPEs from external Java code.
Operator overloading
Operator overloading is where you redefine an operator’s behaviour for a particular type, allowing you to create user-defined implementations of various operators.
While you won’t find this feature in Java, (although Java’s handling of + for Strings does come pretty close) both Scala and Kotlin do support operator overloading.
Compared to Kotlin, Scala takes a much more lenient approach to operator overloading. It lets you define an almost unlimited set of operator-looking functions. Used responsibly, Scala’s flexible approach to operator overloading can make your code much more human-readable: a+ b
is easier to read than a.plus(b)
. This feature also makes Scala a good fit for designing internal domain specific languages (if you want to design external DSLs, there are several powerful parser combinator libraries available for Scala). However, like all of Scala’s advanced features, used incorrectly, operator overloading can result in code that’s difficult to decipher, particularly if you’re new to Scala.
Kotlin attempts to strike a balance between power and readability by allowing you to overload the basic operators that are already in the language (+, – etc.) while preventing you from defining entirely new ones. In Kotlin, you define an operator by implementing the corresponding standard function and annotating it with the keyword “operator.”
These restrictions mean that most Kotlin operators are easy to understand, even for developers who are just getting started with Kotlin. The downside is that Kotlin’s operator overloading doesn’t give you anywhere near the same level of flexibility and power that you get with Scala.
Inlining
Inlining is an optimization that lets you eliminate call overhead by replacing a function call site with the actual function code. Inlined functions tend to run a little faster than normal functions, making inlining a perfect example of how lots of small tweaks to your code can add up to a significant performance boost.
Java’s compiler will perform inlining automatically, but the Java language doesn’t actually provide you with a way of inlining functions manually. If you do make the switch to either Scala or Kotlin, you’ll gain the ability to inline functions manually.
In Scala, you can request that the compiler try to inline a method by annotating it with @inline
, for example:
@inline final def f1(x: Int) = x
Note the word request — ultimately, the compiler has the final say in whether this function is actually inlined or not.
In Kotlin, whenever you use the ‘inline’ keyword, the compiler will always inline the function. Be aware, however, that inlining duplicates the function body at each call site, so heavy use of the ‘inline’ keyword can cause your code to grow out of control.
Essentially, you need to be much more careful about where you use manual inlining in Kotlin, compared to Scala. In particular, you should avoid inlining large functions that are used in multiple locations throughout your code.
Data Classes
Scala’s case classes and Kotlin’s data classes serve a similar function. They both provide you with a way of representing a data-holding object without having to write a ton of boilerplate code.
Annotating a regular class with the ‘case’ (Scala) or ‘data’ (Kotlin) keyword triggers auto-generation of much of the boilerplate code associated with data model objects, including toString, equal, and hashCode, plus accessor methods and setters.
However, one notable difference is that Kotlin cannot automatically infer the constructor parameters, so you’ll need to declare them as either val
or var
. For example, here is an example of a Scala case class:
case class Date(month: String, day: Int)
But the Kotlin equivalent would be:
data class Date(var month:String, var day: Int)
Conclusion
While you can compare and contrast any programming languages, when it comes to deciding which language is “better,” there’s no single answer that’s going to work for everyone.
Whether Scala or Kotlin presents a better Java alternative for you in particular is ultimately going to depend on what you’re looking for in a programming language, how you plan on using this new language, and your reason(s) for moving away from Java in the first place.
If you’re generally pretty happy with the features that Java offers, but are frustrated by the amount of boilerplate code you have to write, then you might want to take Kotlin for a spin. However, if you’re fed up with Java itself and are craving some more advanced and powerful features, particularly if you’re working with big data, then Scala offers a strong alternative to Java — if you’re willing to spend a bit more time getting up to speed with your new programming language.
Informative blog. Good. About analyzing Android GC logs http://gceasy.io/ is good. It is free web tool. You have to upload your GC logs to their server, and results are provided online.
Aside from the things listed here, Kotlin Native is also very important. Compared to Scala, I can easily build write multiplatform apps with Kotlin (Android, iOs, and Web)
I was really trying hard, but your arguments are just not convincing enough for me to abandon Java.
NPEs can be dealt with using the Optional class. Data classes are achievable using Lombok. Overloading operators is evil, Java doesn’t support it intentionally. Inlining rarely leads to noticeable performance improvements (besides, javac inlines code anyway).
Lombok actually leads to some long compile times due to the way it modifies the AST. It’s effectively hacking the JVM in an unsupported way.
You are right that most of what you can do in Kotlin, you can do in Java. The difference is that it takes a LOT less code, and it’s far more readable in Kotlin. Readability = maintainability.
At the end of the day, Kotlin is a higher level abstraction over Java, and like other higher level abstractions, it allows you to be more productive. Kotlin leans on the compiler to ensure that your higher level programming doesn’t come at a runtime cost, and the compiler has been optimized such that incremental compiles are actually faster than Java.
As someone who has been programming with Kotlin for several years, it’s hard for me to go back to just plain Java. Everything feels like it’s getting in my way. I’d highly recommend giving Kotlin a try, especially if you are already familiar with the gradle buildsystem.