The document discusses mixing Scala and Kotlin code. It provides reasons why a company using Scala may want to adopt Kotlin, such as it being easier for mobile developers who prefer Kotlin. It also notes reasons to continue using Scala, like existing Scala code and its powerful features. The document outlines some challenges in mixing the languages, like differences in collections and functions, but provides solutions like converting between the types. It recommends it is easier to call Kotlin from Scala than the other way around.
2. Agenda
â What is Depop
â Why?!
â Collections
â Nullability
â Functions
â Coroutines
3. Depop
Building the most diverse, progressive
Home of Fashion.
â Fashion marketplace app for the next generation
to buy, sell and discover unique fashion.
â Community of like minded creatives, young
entrepreneurs and sustainable enthusiasts who
are transforming the fashion industry.
â Globally, over 26 million users on the platform in
147 countries, and 90% of our active users are
under the age of 26, or Gen Z.
â As an app based platform, Depop combines the
familiarity of social media with the mechanics of
a resale marketplace.
â Our Mission is to Empower our community to
create a new sustainable and equitable fashion
system.
9. Mobile Developers â€ïž Kotlin
â Kotlin is the main language
on Android
â Conceptually closer to Swift
than Scala
â Great for Backend For
Frontend approach, where
Mobile engineers control the
API layer
11. def doSomething(properties: Map[String, List[String]])
fun doSomething(properties: Map<String, List<String>>)
Type mismatch:
inferred type is kotlin.collections.Map<String, kotlin.collections.List<String>>
but scala.collection.immutable.Map<String!,
scala.collection.immutable.List<String!>!>! was expected
đ€
đ±
Collections
18. def executeBlock(block: () => Unit) = {
println("I'm going to execute it!")
block()
}
fun executeBlock(block: () -> Unit) {
println("I'm going to execute it!")
block()
}
Functions
=?
19. MainKt.executeBlock(() => println("Hello from Scala"))
Error: type mismatch;
found : Unit (in scala)
required: Unit (in kotlin)
MainKt.executeBlock(() => println("hello"))
Functions
24. class AsyncKotlinClass : CoroutineScope {
override val coroutineContext = Dispatchers.Default
fun getCatAsync(name: String) = async {
Cat(name)
}
suspend fun getCat(name: String): Cat {
delay(100)
return Cat(name)
}
}
Coroutines
25. val asyncKotlinClass = new AsyncKotlinClass()
val res = asyncKotlinClass.getCatAsync("Fluffy")
val cat = res.await()
Error: not enough arguments for method await:
(x$1: kotlin.coroutines.Continuation[_ >: Cat])Object.
Unspecified value parameter x$1.
val cat = res.await()
Coroutines
26. val asyncKotlinClass = new AsyncKotlinClass()
val cat = asyncKotlinClass.getCat("Fluffy")
Error: not enough arguments for method getCat:
(x$1: String, x$2: kotlin.coroutines.Continuation[_ >: Cat])Object.
Unspecified value parameter x$2.
val cat = asyncKotlinClass.getCat("Fluffy")
đ±
Coroutines
28. import kotlinx.coroutines.future.*
fun getCatAsync(name: String) =
async {
Cat(name)
}.asCompletableFuture()
import
scala.compat.java8.FutureConverters._
val asyncKotlinClass = new
AsyncKotlinClass()
val res =
asyncKotlinClass.getCatAsync("Fluffy")
val cat = toScala(res)
Coroutines
29. Summary
â Reasons to adopt Kotlin in a Scala company:
â Easier to adopt
â Mobile Developers love it
â Reasons to keep using Scala
â Very powerful language
â Lots of code already written in it
â If you need to mix Scala and Kotlin
â Easier to call Kotlin from Scala than Scala from
Kotlin
Hi,
My name is Alexey Soshin, Iâm a Solutions Architect at Depop,
And today we are gonna talk about mixing Scala and Kotlin
So, the agenda for this evening.
First shortly about Depop
Then why would we even consider mixing Scala and Kotlin
And then weâll dive into different topics.
So for today I want to cover collections, handling nulls, working with functions and coroutines
Sounds good?
Depop is a marketplace for fashion. We have about 25 million users globally, 30 million items, and more than one hundred thousand items added every day.
In terms of engineering, we are about one hundred engineers at the moment, and around 200 microservices, which are mostly written in Scala.
We also have a Python monolith that weâre slowly breaking down, but I wonât talk about that today.
Every time I even mention this talk, people ask me: but why would you even do that?!
Well, there are a few reasons.
Scala came out in 2004, so it has at least 7 to 10 years of active development on top of Kotlin.
So, companies have a lot of code already written in Scala, a lot of libraries, and we want to reuse that.
Now, thereâs a dinosaur in the room, and itâs of course Java.
But scenarios where you need to mix Scala and Java or Kotlin in Java are actually well supported.
Because authors of both languages knew that Java has a huge codebase, a lot of libraries, and you want to make sure that you can make good use of them.
If you wanted to throw everything mankind achieved since 95 out of the window, you could try Go instead.
Okay, so why not simply keep writing everything in Scala then?
There are a few reasons for that.
First, Scala engineers are hard to find. There is a lot of competition on the market for them.
And once you hire them, you want to put them on the most difficult tasks.
But not all of the tasks in your company are difficult. So, Kotlin is a good way to diversify your codebase.
https://unsplash.com/photos/dxFi8Ea670E
And the reason Scala engineers are hard to find is because Scala is a hard language.
I have another talk where I try to convince the audience that itâs not that hard, but in general, it is.
I encountered it mainly at Wix, where we were hiring a lot of graduates.
And those were top graduates from top universities. But still for a lot of them functional programming in Scala was hard. It took them months to get productive.
The courses in the university are mainly C, Java, Python, and all those are mostly imperative, almost procedural languages.
So again, I would advocate Kotlin for the places that have a lot of juniors and struggle to onboard them well.
https://unsplash.com/photos/WiKEnlt6Z3U
And finally, thereâs the Backend for Frontend services.
Well, hopefully I convinced you now that there are some valid reasons to mix the two.
The main goal is always to reuse the Scala codebase, Scala libraries that the organisation already has, in Kotlin microservice.
Iâm not advocating for putting Scala and Kotlin code in the same microservice. Although
Now, letâs dive into the problems, I donât like the word challenges, that youâll be facing.
https://unsplash.com/photos/Rs9ypWXB1vE
So, letâs start with something that seems relatively simple.
Compatibility between data structures
So, if we look at those two functions, one is written in Kotlin, another is in Scala, we, as people, can argue that their input is exactly the same.
But if we tried to invoke one passing the input to the other, we would get this friendly error message.
And that will be a common motive in this talk. Since weâre on JVM, it may seem like every should just work.
People were asking me why was I hired as a Principal Engineer to solve those kinds of issues.
Should it you know, just work? No, it shouldnât.
So, thatâs what we want to do. Just call a Scala method from Kotlin that receives a map of lists of strings.
For that in Scala, weâll need the help of JavaConverters, and to have another adapter function.
Notice that here w use Java Map and Java List, instead of Scalaâs
Thatâs because Kotlin has built in support for them.
But thatâs not all.
Even with JavaConverters, we can convert Java map to Scala map, but that wonât do a deeper conversion.
So then we need to iterate over map values and convert each of them to a Scala list too.
But this doesnât produce the correct map yet, so weâll need to call toMap on a map, to get the map we want.
Fun!
Those two have similar meanings, both indicate possible absence of value.
But how can we integrate between them?
So, your Kotlin function works with something that is a String or null.
And Scala likes to receives those as Option. But nullable string is clearly not on Option of a string for the compiler.
Kotlin extension methods to the rescue.
I guess everybody here like functional programming. Functions are great.
Letâs dive into that.
On the left we have a higher order function definition from Kotlin
And on the right we have the same definition in Scala
You need to squint really hard to notice the difference
But are they really equal?
So, letâs try to pass Scala lambda to this Kotlin function
And we get this error, saying that Scala Unit is not a Kotlin Unit
Well, in the hindsight, that totally makes sense
Those are two totally different classes
So, we figured out that those two are definitely not the same
And we could see that even earlier, if we just had looked at the classes behind the lambdas
So, we figured out that those lambdas are represented by two different classes.
If we change the return type of the lambda, the problem would still be the same.
Right?
Turns out, they are interchangable
You can pass Scala lambda to Kotlin, and you can pass Kotlin block to Scala.
So, in fact, Function in Kotlin and Function in Scala are interchangeable, as long as their input and output is interchangeable.
I guess everybody here like functional programming. Functions are great.
Letâs dive into that.
Coroutines are similar to lightweight threads or fibers.
So, here we have a Kotlin class with two methods
One is asynchronous method, that returns a deferred result
And another is a suspending method, which is like blocking, but instead of blocking a thread, it suspends the coroutine
CoroutineContext is like an execution context
Letâs try using the first one from Scala
It even may look like itâs working, until you try to get the result
Await() method has no arguments, but compiler demands that we pass it something called continuation as the first parameter.
Doesnât make any sense.
Ok, letâs try to invoke second method. It should be simple.
Now although we have one argument, weâre required to pass Continuation as a second parameter. Again, no luck.
Trying to complete Scala future from Kotlin wonât work, because itâll need execution context.
So, youâll be passing the gorilla and the entire jungle, when you just wanted the banana.
But thereâs something else that will help us. And this âsomething elseâ is weirdly enough - Java
We can import coroutines/future package in Kotlin, and weâll get a method that converts Kotlin Deferred value into CompletableFuture
Now, Java CompletableFuture can be converted to Scala future.
Or to any other future, for this matter.