Top five items that bugs me in Kotlin

I am a very experienced programmer and, I have been with Kotlin for a few months and I love it. However some stuff are annoying. I know that it’s a very personnal list but here is my top five.

a) Destructuring multiple function return demands var or val keywords.
It’s very artificial for me. Sometimes it forces me to copy that variable to another variable if inside curly brackets or I need to create artificial classes with no cohesion.

b) Most custom inline symbol operators used defined demands “” or there is no priority setting. I’m doing scientific programming, so it’s natural I define ^ power operations, it’s best than pow, but yet annoying. I need use parenthesis everywhere.

c) Android Studio is guilty of this, but Step Into enters in classes and objects non-configurably, as in Java. So I need to go to called function by hand and after select Run to Cursor, otherwise it is an eternal pain

d) Kotlin type check is great, but some decisions of Kotlin designers are exaggerated. 1/2 returns 0. it’s not intuitive at all. Division (/) it’s a rare operatior where people wait for Double or Float and not Integer or Long. Some languages uses another operator for integer division.

e) You cannot skip parameters when one calls a function, using 2 commas in a row, that the skipped parameter hast a default value defined. There is no logic for that language design decision, in my opinion, because default value is there exactly for this.

e) Yes but using two commas renders (imho) ugly code
eg: fun f(x : Int, y : Double = 0.0, z : String)
f(0, , "")
seems ugly versus using named parameters
f(x=1, z="asdf")

I personally love named parameters and I used them as often as I could. This language feature increases code readability so much.

5 Likes

@andob, it’s a matter of opinion, of course. I use named parameters and I like it, but there are many situations where skip parameters it’s more practical. Imagine a function with 10 parameters. Use named parameters can be a very verbose style.

1 Like

I get the feeling your background is in non-C family languages, is that right? :slight_smile:


Integer division is usually handled the same way across C style languages. If Kotlin were to convert integer math to floating-point math it could lead to a lot of confusion and would be unexpected behavior for most users.


Usually, a function with more than 3 or 4 params would be a big red flag in Java programs. Named parameters make functions with more than 3 params, which would normally be a code smell, tolerable.


A lot of scripting programming languages (e.g. Python) aim to be concise. It sometimes works to make the code more readable but seeking conciseness often leads to unreadable code-golf. Java aims to be readable in the opposite way, by being explicit with nothing hidden or left out. Again, it sometimes leads to very readable code but often leads to an unreadable sea of verbosity.

Kotlin tries to be readable first. Being concise is part of that, but it’s not the ultimate goal to have the fewest characters. Being explicit is part of that, but it’s not the ultimate goal to require every detail captured in code.


There is definitely some opinion as to which design approach is more readable.

Some people prefer:
getMetadata(10, , , , "/data/", , validJson)
It’s fewer characters and takes up less space.

Others prefer:
getMetadata(pages=10, postfix="/data/", filter=validJson)
It’s clear what params are supposed to be used and what there for.
I’d have no clue what “validJson” or “/data/” was being used for in the function without the name.
And I’d sure be confused by all of the skipped params.

Regardless, I’m sure the solutions to any pain points in Kotlin will based on the aim to be understandable and readable so that the language can improve from the practical lessons learned from Python and Java.

From the KotlinConf 2018 keynote:

5 Likes

@arocnies, my background was Pascal. I always have hated C.

I agree that named parameters is more readable, but If this approach were taken to extremes, positional parameters should be prohibited in Kotlin. It’s not the case. Since positional parameters are allowed, I do not consider that two commas in a row make this worse…

Regarding integers division becoming a float type, I understand your point, but it’s weird to the scientific community, because everryone knows that 1/2 is 0.5. See Python, R, Julia or Matlab languages. Julia and MatLab are just in time (JIT) compiler languages. Julia was created in 2012 in MIT. I don’t see any problems that the inline operator ‘/’ gives a Double. It is very rare for someone to write 1/2 like 0… My old Pascal language and math people think in 0.5. Indeed, C gives 0, but, as I’ve said to you, I’m a Pascal guy

For me, C it was a setback, but a setback that has conquered the world. The readability has never been the same as in Pascal, Modula 2 or Ada. ++, += and others constructs at start was inscrutable

For real, the items d) and e) don’t bother me so much, but the first 3 items are worse for me.

Re: (d) 1/2=0

I suppose I’m so accustomed to that from other languages, that I don’t see anything strange about it.

But changing the behavior now would break a lot of existing code, wouldn’t it?

3 Likes

Yes, I agree. Nothing to do about it. The game is over. However the other items are not like this, because are new features.

Can you provide examples for (a) and (b)? I’m not clear on what they are.

Of course

a) Destructuring multiple function return
An old post of mine

b)
In my code, I’ve used my own " v" power operator. In this case, I need to use a letter. I cannot use the more intuitve ^, unless I used quotation marks

inline infix fun Double.v(exponent: Int): Double = this.pow(exponent)
inline infix fun Double.v(exponent: Long): Double = this.pow(exponent.toDouble())
inline infix fun Double.v(exponent: Double): Double = this.pow(exponent)
inline infix fun Int.v(exponent: Int): Double = this.toDouble().pow(exponent)
inline infix fun Int.v(exponent: Long): Double = this.toDouble().pow(exponent.toDouble())
inline infix fun Int.v(exponent: Double): Double = this.toDouble().pow(exponent)
inline infix fun Long.v(exponent: Int): Double = this.toDouble().pow(exponent)
inline infix fun Long.v(exponent: Long): Double = this.toDouble().pow(exponent.toDouble())
inline infix fun Long.v(exponent: Double): Double = this.toDouble().pow(exponent)

I’ve accepted to use v, but I have some problems:

Unfortunately the v priority is lower than +

        println(2 v 5)  // 32 (ok)
        println(2+3 v 3)  // 125 (29 expected)
        println(3 v 2 + 1)   // 27 (10 expected)
        println(2 + 3 v 2 + 1)  // 125 (12 expected) 

So I need always to use parenthesis. it’s not intuitive, but it works well

I agree with point a and b. It should be possible to reassign vars using destructuring. I don’t really understand why it’s prohibited.
Infix IMO is just not a well thought out feature. It is great for DSL, but outside of that it just leads to problems. As you said there is no way of defining the priority of infix functions. They pretend to be an alternative to custom operators, but they aren’t really. We have the same problem with binary “operators”.
At first I was experimenting with them but now I just don’t use infix anymore.

4 Likes

I am also Pascal guy initially (and I mostly agree about C, C is OK, but C++ was a mistake), but I have a long history with java, so kotlin things are OK for me.

The integer division is not strictly C/Java thing. The problem is that in strictly typed language, you have to make a decision about those things this way or that way. I think that a proper way is to forbid division on integer numbers and require explicit cast for that (in KMath we separated ring from spaces so division is not available for int-specific entities).

The operator overloading is a controversial point. One one hand, you usually want those operations, on the other hand, it immediately becomes abused (see Scala). We already see abuse of those operators that are available for overload in Kotlin, so it probably was a good idea to prohibit more.

1 Like

1/2 be 0, bugs me, but it’s personnal and it’s not a big deal. I agree with abuse of overloading. It’s not good because change each program in a dialect. The matter is that ^ should be a natural operator in Kotlin with right priority. It’s so common operator, even in highschool. Pitagoras’s theorem don’t let me lie…

1 Like

Well, it is common in mathematics (actually not so common), but is not otherwise. Proper brackets really solve the problem.

1 Like

Yes. I use my user defined v operator with no problem. My programmation is scientific. So there are many expressions in my code and good readability is mandatory. v with parenthesis is more readable than pow binary operator.

1 Like

Yeah, it is a matter of opinion. In kotlin you can create your small set of extensions for your project of even little flavour library. For example, we now have Double flavored extension for kmath.

In case you do not know, we have a chat for that.

I will check it. Thanks for the tip.

Others could argue that ^ is a perfect fit for bitwise xor operator. Should it have the same operator priority in this meaning as the power operator has?

6 Likes

^ is adopted as power operator in hundreds of programming languages (including the overwhelming Excel) and as xor in C++ , Java. and Python.

Most languages uses xor in extense, xor is more readable than ^ operator, in my opinion. However, if Kotlin adopt ** as Phython, i will be very happy …

From Wikipedia one can see that most languages define some operator for power.

A inline power operator helps that an expression in that programming language looks like a real math expression

1 Like

Groovy uses ** and I can’t say that it is much better than pow. Power operation is not used very frequently. If you want to have maths-like display, it is better to write an IDEA which will visually transform (a pow b) into a^b. I have some experience with languages like BlackBox and Julia which are designed to make math formulas look natural. Well, it is pretty, but not really good from programming point of view.

1 Like

I’m developing for Android phones in Android Studio a scientific app.

So the obvious choice is Kotlin or Java.

I prefer Kotlin thousands of times. So, no problem for me, It just a way to let off some steam.

Again, it’s a matter of opinion, but I think that (a ^ 2 ) it’s much clearer than pow(a,2).

See Pithagoras Theorem

Compare

c = sqrt(pow(a,2) + pow(b,2))

with

c = sqrt(a^2 + b^2)

For me, it is obvious that the second one is easier!

But I’m fine and happy with my custom v operator. I’m not going to die I will not die because of some excess and weird parentheses.

It’s funny, because pow is even more verbose than ^, it takes the fluidity out of the expression and it is less readable. There is no advantage.

I’m doing heavy calculation with complex numbers, so pow for me It looks horrible in my big expressions.

2 Likes