String concat with Integer - implicit type conversion

Hello I noticed that you can concatenate string literal with integer by + operator:

val i = 10
val s = "Hello world" + i

I think this is a bad design, there must be an exception.
There is great alternative for this:

val i = 10
val s = "Hello world $i"

Links:
https://news.ycombinator.com/item?id=14867254
https://news.ycombinator.com/item?id=15701823

They’re both the same thing, only the first involves operator overloading.

Personally, I think operator overloading is the work of the devil, but others may disagree. I think similarly many people will say that the first is a perfectly acceptable use of operator overloading.

Even if this was bad design (which we don’t necessarily agree with), it’s too late to change it at this point: removing this feature would break huge amounts of existing code without bringing any tangible benefits.

6 Likes

The ‘plus’ operator is actually overloaded on the String class so that you can append the string representation of any object, not just an Int, to the base string.

This also works in Java and C# though, in the case of the former which doesn’t have operator overloading, it’s built into the language and is probably the reason why it’s been carried through into Kotlin.

In the case of numbers, it can of course be confusing if the base string itself is numeric but, otherwise, I see no great harm in it even though I normally prefer to use string interpolation instead.

Although some developers love operator overloading and others hate it, I think myself the Kotlin designers have struck a reasonable compromise between the two positions with the relatively sane form of operator overloading (compared to C++ or Scala, say) we have in the language.

5 Likes

For me operator overloading is acceptable for math object like matrices, vectors etc.
Operator overloading not bad, but I think that the developer himself must decide where use this, and for me it was a surprise that the String has it by default.

3 Likes

It comes from Java. There you have object to string concatenation but no “smart” strings. In Kotlin it is much more logical though. Any object has toString method so it is no longer language construct, but simply operator overloading.
Removing it is not an option, but I really do not see the problem. It is rather hard to confuse number for string. The implicit integer to double conversion in java gives much more troubles.

Funny thing, the reverse (i + “Hello world”) is invalid

Ah, operator overloading, elegant and intuitive as ever. Is the fix to make + noncommutative for numbers?

If you want to prepend a number to a string, then the trick is to use an empty string first:

val n = 2 
val s = "" + n + " at a time" 

However, this is definitely a case where string interpolation is much nicer:

val s = "$n at a time"

You can always do something like:

operator fun <T> T.plus(str: String) {
  return this.toString() + str
}

But I would not do it because it could clash with some existing definitions and in some cases could produce not very obvious results.

1 Like

Can you show an example of an actual bug in a Java or Kotlin application caused by incorrect use of string concatenation? Given that the feature has always existed in Java, such examples must be really easy to find if the design is really bug-prone


2 Likes

Not in kotlin since I just started, but I make regularly the mistake in python

Since you rarely declare types explicitly in Kotlin code, you can accidentally end up with weird behaviour when you least expect it. Consider the following code:

val foo = getSomeValue()
println("foo = $foo")
val bar = foo + 10
println("bar = $bar")

If the first println() call prints 500, will the output of the second be 510 or 50010?

If there was no operator overloading, then the behaviour of the above code would be more clear.

By the same argument you would need to prohibit function overloading.

Sounds like a good idea.

The difference of kotlin from C++ is that you can avoid operator overloading if you do not like it. Just use str.plus(2) instead of str + 2. I Agree that operator overloading should be used with care, but in my opinion kotlin team reached reasonable compromise.

bad idea. personally I can’t see any benefits of that behaviour. plus I don’t think that language should force me to do so.
btw, most kotlin people comes from java world, where such operation is absolutely legal, so for what reasons it’s shouldn’t be same in kotlin?

I think the point of Kotlin is to escape the mediocrity of Java, not replicate it.If someone likes Java language features they can always use Java.

But given the nature of JetBrains’ business, they could not really afford to stray too far from Java. I’m hoping that with the introduction of Native Kotlin that they will evolve away from Java and one day deprecate some of the most egregious misfeatures they’ve imported from there.

Ok, but I still not understand what benefit of throwing error for string + number operation?

If you accept that operator overriding is ok, then there’s nothing really wrong with it and no benefit to disallowing it. The OP is saying that people should never be able to write this because it’s more likely to be an coding accident than a legitimate expression.

The “issue” kind of assumes that the person writing the code isn’t familiar with how operators are overloaded.