Looking at language statistics in last rounds I have wondered why so many Java and so extremely low Kotlin coders?
Kotlin, in a rough sense, is modern replace for Java, so...
If you are Java-coder then I am curious why you not change Java to Kotlin?
I don't want to note basic advantages of Kotlin which described everywhere. But it is language with modern syntax, and I think it is cool for cp almost as Python. I have more than one year experience of coding in Kotlin (but not cp!!), and I can describe my feelings as "I will never write even single line again in Java".
Maybe you remembered Kotlin as not so cool language when it was 1.4 but now (1.7 in moment of writing this blog) both syntax and std lib have improvements. For example, instead of readLine()!!
now it is readln()
. Or modulo function
val MOD = (1e9 + 7).toInt()
println((-1).mod(MOD)) //1000000006
println(((MOD-1L)*(MOD-2L)).mod(MOD)) //2
Usage of lambdas in Kotlin is awesome. Just look at this custom comparator:
data class Segment(val l: Int, val r: Int, val id: Int)
...
segments.sortWith(compareBy<Segment> { it.l }
.thenByDescending { it.r }
.thenBy { a[it.id] }
)
Last what I really like is extensions, great for templates/libraries
fun IntRange.firstFalse(pred: (Int) -> Boolean): Int {
var l = first
var r = last + 1
while (l < r) {
val m = (l + r) / 2
if (pred(m)) l = m + 1 else r = m
}
return r
}
//usage:
val i = (0 .. 2e9.toInt()).firstFalse {
1L * it * it <= s
}
Probably because Kotlin is waaay less popular than Java. Add to that the fact that the vast majority of universities teach Java/Python and not Kotlin, which skews the ratio Java:Kotlin even more in the young demographic.
I assume most Kotlin users here are either older (working as SWE) or stumbled on Kotlin because of Android.
well, I love kotlin, in fact, I have given a lot of contests in kotlin on codeforces and other cp platforms as well. Now, I don't use kotlin anymore because of the outdated kotlin versions on other cp platforms. Codeforces has the always maintained the latest versions of the language, so I don't have any problem writing modern kotlin code and submitting it on codeforces but I have to face a lot of problems when I write code in kotlin(some modern kotin syntaxes) and when I run it on let's say codechef, it simply gives a compilation error. The same goes for the leetcode as well. Now you can think of happening this midway through the contest. So that's why I had to come back to java, so that I could give contests on every platform.
I agree there should be more usage of kotlin. Maybe testers can provide solutions in kotlin ?
Java is a lot more well-known and well-supported (for example, not all contests allow Kotlin).
If you want to make the effort to move away from Java to something better, you'd probably switch to C++ instead (like I did, after many years of doing competitive programming in Java).
I don't understand how primitive types works in Kotlin. They say
Well, first of all, I don't understand what that means. Let's assume it means something like "Int, Double etc. are equivalent to primitive java types". But then why do we need IntArray and the like?(and yes, I know the answer is that IntArray is int[] and
Array<Int>
is Integer[]).Now let's look at
val MOD = (1e9 + 7).toInt()
. How is this going to work? Which object istoInt()
going to be invoked on? Or is it going to be optimized during compilation?If it's the former then all of this is kinda useless for CP. If it's the latter, it's very cool of course but kind of... opaque? Is this the case for every method of Int(Double)?
All in all, many questions, almost no answers(or I can't be bothered to try and find them).
About primitives, it may be helpful to read about inline classes. In fact, you can think about Int in kotlin as an inline class over primitive int from java. So rules are the same — it would be always primitive, except in cases where it is used as more generic types. Typically, there are three cases for that:
All of this is basically the limitations of jvm platform. You can't reasonably have primitive in any of them on java (at least until Valhalla project is done). In fact, that is a rule. If there is a reasonable way of having primitive in JVM — Int/Double/Long/Float would always be primitive.
Probably, the only case against this intuition is Array, which follows common rules of generics, and is not optimized to Primitive[], while they can be on the first view. But things are more complex in touch with other features. The core problem is primitive is not a java object, so in fact, if Array would be int[] and not Integer[] it would be a corner case in all overload rules and etc. And I'm not even speaking about some types like
Array<out Comparable<Int>>
which should be able to storeArray<Int>
,Hiding details, which are not important, is one of the main ideas of Kotlin language. But "being not important" is quite a domain-specific thing. And this requires some experience to avoid performance penalties on wrong usages in different corner cases.
As a man who competed in ICPC WF using Kotlin and developing things on Kotlin @ JetBrains, I have a few things to notice:
Multi-dimensional DP might be hard, compare
int[][][] a = new int[1][2][3]
andval a = Array(1) { Array(2) { Array(3) } }
,int[][][]
andArray<Array<IntArray>>
.When you're comfortable with
map
,filter
and similar operations, you might fall in a pitfall when you for example want to iterate over a range of numbers (0..x
) and filter them, map and so on. You may assume if will work just as fast as a usualfor
loop, but in reality it's much much slower, because Kotlin will collect those indices to aList
first and then operate with lists, which is much slower thanfor
loops even in Java.Sometimes you want to write for loops in c-style to have some custom break conditions or increment operations, but in Kotlin you can't. Just remember all those Fenwick trees, Iterative Segment trees (down to top for-loops), FFT and so on.
Sometimes it's way too safe. You cannot have an array of nulls and work with it like in Java. In Java you can have
State[] a = new State[n]
, in Kotlin you either have a nullable arrayval a = Array(n) { null as State? }
or you hack the compile-time with uglyval a = Array(n) { null as State? } as Array<State>
.By the way, Kotlin has lots of cool things such as nice syntax, data-classes, easy-looking lambdas, extension functions, local functions, operator overloading, inline classes and so on
As for me, Kotlin is doing a great job in terms of replacing Java, and if I know that I can solve some problem on Kotlin, I'll do it. Otherwise I'll go with C++. Java becomes useless here. You either have a nice and debug-friendly Kotlin, or unsafe but fast asf C++.
fun <reified T> array2d(a:Int, b:Int, init: (Int) -> T) = Array(a) { Array(b) { init(it) }}
in your template can help you. It can be used asval a = array2d(1, 2) { IntArray(3) }
, which probably can be wrapped to intArray3d helper if you wish.tailrec
helps in several situations, that's truearrayOfNulls
createsArray<T?>
whereas if you have an array, you want to deal withArray<T>
, this is what I meant. You still need a cast to an array of non-nulls.Oh, I got it. Yes, you can't disable null-checks on one variable.
I truly can't understand 4'th case. If array is non nullable, why it must contain nulls?
Usually, you don't want to create a non-nullable value just to put it in the array and never use it.
In Java, you just write
State[] a = new State[n]
, then it will contain nulls and you have to manually deal with it.In Kotlin, in order to have an array of non-nulls, you should either use a cast as in the comment above, or create and initialize the object inside:
val a = Array(n) { index -> State(...) }
which is not free and in most cases does not make any sense.btw, sparky_master_wch1126 also use kotlin