Disadvantage of Kotlin : You must know before use

2
2070
Disadvantage of Kotlin
Disadvantage of Kotlin

In my previous articles we discuss about advantage of Kotlin and create first application in Kotlin using Reddit API. But today we discuss about disadvantage of Kotlin and Please treat it as personal opinion & comment if you have solutions for problems listed below.

Although Kotlin is great, it’s not perfect. Here are a few aspects of the language that I’m not in love with.

1No namespaces

Kotlin allows you to define functions and properties at the top level of your files. That’s a great feature, but it can cause some confusion when combined with the fact that all top level declarations are referenced unqualified from Kotlin. This can sometimes make it difficult to tell what a function is when reading one of its usages.

For example, if you define a top level function:

fun foo() {...}

You will call that function as foo(). If you have a function with the same name in a different package, it’s not obvious from looking at the call site which function is being called. You can fully qualify the name of the function with the entire name of the package that it’s defined in, but given Java’s convention of very deep package names, that’s not ideal.

RecommendedWhy Kotlin Anko is better than Java XML for Android?

One workaround is to approximate a namespace by using with a singleton object class.

object FooActions {
    fun foo() {...}
}

That allows you to refer to the function as FooActions.foo() if you’re only calling the functions from Kotlin, but it’s not as pretty if you have Java code that needs to call that function. From Java, you have to refer to the function as FooActions.INSTANCE.foo(), which is certainly not ideal. You can avoid the INSTANCE step by annotating your function with @JvmStatic, which is about the best you can do currently. That’s not a big deal, but it’s some boilerplate that wouldn’t be necessary if Kotlin had namespaces.

2No static modifier

Following on the previous point, Kotlin has unusual handling of static function and property declarations that are called from Java. It’s not bad, but it feels dirtier than necessary. For example, the Android View class defines some static constants like View.VISIBLE and static methods like View.inflate:

public class View {
    public static final int VISIBLE = 0x00000000;
    public static final int INVISIBLE = 0x00000004;
    public static View inflate(Context context, int resource) {...}
}

The declaration is simple. In contrast, here’s the equivalent Kotlin:

class View {
    companion object {
        @JvmField 
        val VISIBLE: Int = 0x00000000
        @JvmField 
        val INVISIBLE: Int = 0x00000004
        @JvmStatic
        fun inflate(context: Context, resource: Int) {...}
    }
}

Although the Kotlin version isn’t terrible, it’s more verbose than I would normally expect from the language.

See this : Create dynamic layout in Android

If you skip the annotations, then Java code will have to use awful syntax to refer to your fields:

// With annotations:
View.VISIBLE;
//Without annotations:
View.Companion.getVISIBLE();

It feels odd that there are no better ways to create static functions and properties. I know that companion objects are real objects and can do stuff like implement interfaces, but that doesn’t feel like a compelling enough use case to completely replace normal static declarations.

3Automatic conversion of Java to Kotlin

This was the first topic in the list of things I like about Kotlin, and it works well. But because it work so well 80% of the time, many of the cases where it fails can be frustrating.

Javadocs are often mangled, especially any paragraphs the wrap lines. Static fields and methods are converted to plain declarations on the companion object, which breaks any Java code that previously called them unless you manually add @JvmField or @JvmStatic, respectively.

All of these problems will certainly get fixed as the Kotlin team has more time to work on the converter, so I’m optimistic in this case.

4Required property accessor syntax

Kotlin has the great syntactic sugar called “property accessor syntax” that allows you to call JavaBeans-style getters and setters as if they were a Kotlin property. So for example, you can call the Activity.getContext() method by writing activity.context instead of writing the whole method name. If you use the actual method call in Kotlin, you will get a lint warning telling you to use the property syntax instead.

That’s definitely a nice feature, but there are a few cases where method names start with the word “get”, but you don’t want to use the property syntax. One common case is with Java’s atomic classes. If you have a val i = AtomicInteger(), you might want to call i.getAndIncrement(). But Kotlin wants you to call i.andIncrement. That’s clearly not an improvement.

You should also see : How to use Json or Gson in Kotlin?

You can annotate every call site with @Suppress(“UsePropertyAccessSyntax”), but that’s ugly. It would be much better if there was a way to annotate functions you write with a similar annotation that would tell the linter that the function shouldn’t be treated like a property.

5Method count

Writing code in Kotlin will certainly reduce the number of lines of code in your project. But it will also probably increase the method count of the compiled code, which is of course a drawback if you’re using Android. There are a number of reasons for that, but one of the larger contributors is the way Kotlin implements properties.

Unlike Java, the Kotlin language doesn’t provide any way to define a bare field. All val and var declarations instead create a property. This has the advantage of allowing you to add a get or set definition to a property whenever you want without breaking code that references the property. That’s a great feature that removes the need to write defensive getters and setters in the way that you often do in Java.

And finally, here are two design decisions that the Kotlin team made that I strongly disagree with, and that I don’t expect to change in the future.

6SAM conversion and Unit returning lambdas

This one is a really baffling design decision.

One of the best features of Kotlin is the way it embraces lambda functions. If you have a Java function that takes a SAM interface as a parameter (an interface with a Single Abstract Method):

public void registerCallback(View.OnClickListener r)

You can call it by passing a plain lambda from either Kotlin or Java:

// Java
registerCallback(() -> { /** do stuff */ })
//Kotlin
registerCallback { /** do stuff */ }

This is great. But trying to define a similar method in Kotlin is inexplicably harder. The direct translation is called the same from Java, but requires an explicit type when called from Kotlin:

fun registerCallback(r: View.OnClickListener)
// Kotlin. Note that parenthesis are required now.
registerCallback(View.OnClickListener { /** do stuff */ })

That’s annoying to have to type out, especially if you convert some Java code to Kotlin and find out that it breaks existing Kotlin code.

The idiomatic way to define that function in Kotlin would be with a function type:

fun registerCallback(r: () -> Unit)

Which allows the nice function call syntax in Kotlin, but since all Kotlin functions are required to return a value, this makes calling the function from Java much worse. You have to explicitly return Unit from Java lambdas, so expression lambdas are no longer possible:

registerCallback(() -> {
    /** do stuff */
    return Unit.INSTANCE;
})

If you’re writing a library in Kotlin, there isn’t any good way to write a method with a function parameter that is ideal to call from both Java and Kotlin.

Do you know : How to use Lamda in Kotlin?

Hopefully the Kotlin designers change their mind and allow SAM conversions for functions defined in Kotlin in the future, but I’m not optimistic.

7Closed by default

Every downside to Kotlin I’ve talked about so far are mostly small syntax details that are not quite as clean I’d like, but aren’t a big deal overall. But there’s one design decision that is going to cause a huge amount of pain in the future: All classes and functions in Kotlin are closed by default. It’s a design decision pushed by Effective Java, and it might sound nice in theory, but it’s an obviously bad choice to anyone who’s had to use a buggy or incomplete third-party library.

8Conclusion

Kotlin is overall a great language. It is much less verbose than Java, and has an excellent standard library that removes the need to use a lot of the libraries that make Java life bearable. Converting an app from Java to Kotlin is made much easier thanks to automated syntax conversion, and the result is almost always an improvement. If you’re an Android developer, you owe it to yourself to give it a try and share your experience with us via comment.

Share your thoughts

2 COMMENTS

Loading Facebook Comments ...
Loading Disqus Comments ...