DEV Community

Discussion on: Kotlin - The Good, the Bad and the Ugly

Collapse
 
martinhaeusler profile image
Martin Häusler

First of all, thanks for all the input!

"Semicolons are optional" - in some cases they actually made it a must. Not sure why.

The only case that I have ever encountered in Kotlin where a semicolon was actually required is when you have multiple statements on the same line of source code. Consider this:

// semicolon is actually required here
val x = 3; val y = 5

... however, you can always reformat your code to be one per statement:

// semicolon be gone!
val x = 3
val y = 5

I never encountered any other scenarios where the compiler wanted me to insert a semicolon. And honestly, having more than one statement per line is rather ugly and unnecessary.

The conversion tool is very dangerous. Need to handle it carefully.

I didn't want to open this pandora's box in the article, it's an entirely different discussion. But I agree with you: the tool, while conceptually nice, is indeed not without flaws. The tool is nice when you are learning Kotlin: you can write some Java code, throw the tool at it, and discover how it would look like in Kotlin. However, I would never trust it when it comes to production code.

Many times, Kotlin insists that I tell it the type of the variable, even though it's clear what it is

What you are trying to do in your code is to declare a field with a default value, and expect the compiler to infer the field type from that. While I do agree that this is fine for local variables, I would argue that the same logic does not necessarily apply to fields, because they have a much broader scope (and a longer lifetime). So if you say (in a constructor argument) val x = 3, then do you really want x to be an Int? Or maybe a Double? The compiler can't tell. Again, for local variables this is fine: if you discover that the type was too narrow (i.e. you actually wanted Double, not Int) then you simply go back and adapt your initial value assignment accordingly.

By the way, likewhise the Kotlin compiler doesn't provide type inference for function return values, even though there might be only one path through the control flow of the function which always returns a value of a certain type. But hey, let's be real here - it is still a big step upwards from what Java can do at the moment (Java is slowly catching up in this area though).

And I don't think we really need MutableList.

This is debatable of course. I personally really like it, because it saves me both the trouble and the performance loss for returning Collections.unmodifiablelist(myList) instead of just myList. It makes it clear to everybody which collections are safe to be modified, and which ones should be treated as read-only. I can see though that it is annoying to write Mutable all over the place. Then again, immutable data structures do have a lot of appeal, so maybe we should not use too many mutable collections to begin with.

But, good news is that if you have a class that all of it is static stuff, you use "object"

Oh okay, thanks for the heads up, didn't know that. I agree with you that the companion object was not the best idea they've ever had.

I've heard though that it's possible to overcome it somehow (without modifying the code of the final-class). Do you know how?

As it happens, I do :-) Fair warning: dangerous terrain ahead. You can actually write plug-ins to the Kotlin compiler (whether or not you should do that in practice is another discussion entirely). One such plugin is the All Open plugin, which is primarily required for using Kotlin together with the Spring framework (here's an article that highlights why this is so very much necessary), but the plugin works independently from any library or framework. What it does is that it basically implicitly declares all Kotlin classes as open. This takes us back to the way Java did it. However, note that it does not work on all classes. Data Classes, Sealed Classes etc. will still be final. Also note that with this plugin activated you have no way of declaring your classes explicitly as final anymore. Furthermore, I can't confirm how well the tooling (IDE) plays with such compiler plug-ins.

"Data Classes" - didn't know they are final. Didn't use them much though. Good to know. Made a request about this.

I appreciate the valiant effort, but I'm afraid you will not be greeted with a warm welcome for this request. I've seen more than one discussion thread online about this topic, and the Kotlin devs are quite stubborn about this decision. They claim that it is not possible to have inheritance for data classes because of technical reasons within the generated clone(...) utilities. As I stated in the article, I don't buy that argument. I sense plain old lazyness here.

Collapse
 
androiddeveloperlb profile image
AndroidDeveloperLB

About semicolons, incorrect. It is also required in enum classes (which I don't get why can't we just use "enum" instead of "enum class", BTW) that have extra code and not just values :

enum class SomeEnum{
    VALUE1,VALUE2;

    companion object {
        fun foo(valueInt: Int): Int = 123
    }
}

"...do you really want x to be an Int? Or maybe a Double? The compiler can't tell. "
Of course it can tell. It does it to fields (properties) and variables. What difference does it make if I put it directly in the CTOR...

About MutableList, I mostly just hate that they made it confusing. "List" should have been the same on Kotlin as on Java. Now it means a different thing. On Java you can do whatever you wish with it. On Kotlin you can't.

About making Kotlin open of classes, I mean something else. It was asked somewhere in Google (probably some Google IO lecture), and I think they said that if you insist, you can use Java to override Kotlin, but I didn't understand how.

Really on many (and probably most) things Kotlin did nice things, but on some I just ask myself "why did they do this? This is way worse than on Java...".