The problem is not operator overloading (using + to concatenate 2 strings) but type mixing (concatenating a string and a number). The fact that it’s the same in java is not a good reason by itself to justify it, although there is probably worse risks of worse bugs elsewhere.
No, my argument is that the overload plus operator for Int and other types should not be by default, the developer must decide whether to add or not operators overloading.
I was referring to the commenter prior to me.
Your idea is interesting.
Sorry, but being able to convert things to strings by concatenating them to another string is very useful. It can also be considered to be basic-level knowledge.
Every language has rules (and quirks) to learn. In this case Kotlin has an exception for the plus operator in combination with strings.
Maybe there are some people who get confused by the current behavior of Kotlin. The solution is simple: Study the language better, instead of blaming language design! If we start making languages dumber and dumber every time someone gets confused, we will end up with languages that are terrible.
A simpler or safer language is not a dumber language. Adding features or complexity doesn’t improve a language by itself. That sort of “logic” is what gives us languages like C++. Simplicity and elegance are positive attributes in a language.
The job of a programmer isn’t to understand programming languages, it’s to write software. The less time and mental effort spent learning or grappling with a language is time and effort spent on getting the job done.
Yes, it is. If there are no “surprises”, then I have to write everything out explicitly. Where does that stop? C, assembly, microcode?
Plus, I do not want to be stuck in programming 101 my whole life. I am perfectly capable of understanding classes, overloading, overriding, covariance, contravariance, double dispatch, etc. All these concepts are difficult for some people. Removing these all from the language to prevent mistakes, results in an absolutely horrible language. I am very glad I took the time and effort to learn a lot of concepts, because they allow me to write concise code that gets the goal instead of the manner across.
Of course it is. How can you write software if you do not understand what lines of code do? Everybody will need to study to become a master of their language/paradigm of choice. I cannot imagine anybody starting a computer for the first time, intuitively knowing a programming language, and writing good, maintainable code from the start. I am absolutely sure there are lots of better software developers than me, but I am also absolutely sure they reached that level by studying a lot (no matter what talent they had to start with).
I understand some concepts are difficult. Personally I have great difficulty designing software that only consists of pure functions. But what we talking about here are some very basic rules. If that is too hard to learn, you will be in for a very wild ride: class loading, functional programming, reactive programming, concurrency, etc.
Maybe things look insurmountable now, but I am sure that if you use Kotlin for a while, these “strange” constructs will seam natural to you.
What we could do is to deprecate that plus
operation. It won’t break the existing code and will guide people to use string templates instead of concatenating strings with arbitrary objects.
Personally I don’t see much of use from that operation, given that Kotlin has string templates. When I see one in code, I tend to replace it with template as soon as IDE suggests me to do so.
While I agree that templates are preferable to concatenation, isn’t marking a feature as deprecated a suggestion that it will be removed in future releases?
The meaning of word ‘deprecated’ is somewhat ambiguous in Java all the way to version 8 and addressed in Java 9 (Enhanced deprecation). What exactly is Kotlin’s definition of deprecation?
This is fairly typical of the “macho programmer” mentality, someone who isn’t interested in getting the job done so much as showing how clever they are (they list all the language buzzwords they know, just to prove it). Suffice to say trying to maintain code they write is a nightmare.
And this is what proves it in this case, confronted with a notion that challenges their view, they quickly resort to belittling the other and accusing them of lacking technical prowess (“look at your puny muscles!”). This makes sense, becuase machismo is about insecurity, not strength.
But back to the topic at hand: more complicated language features make code often harder to read, since it’s not obvious what is happening behind the scenes. For instance with operator overloading you need to figure out the static type of each argument as well as the precedence and associativity of each operator for every subexpression starting from the leaves to figure out what methods are actually being called and what’s actually happening.
Probably most the damning criticism of operator overloading is how often compilers are unable to compile such overloaded expressions becuase they can’t infer their static types even with validly formed expressions (you have to rewrite them for the poor compiler’s benefit). Such behaviour makes me think the feature is actually a bug.
Also efficiency slowly becomes impossible with an epidemic of language (mis)features. For instance if I want to increment an integer, I would feel fairly safe that writing n = n+1 would execute in one instruction’s time or perhaps even less, but not if n is a property. Reading and writing to a property can involve an arbitrary amount of code in each case. If you don’t have the source to that code you have no hope of knowing how efficient it will be.
I could go on but let’s just say language features do not come without a cost and it’s not obvious that they (all) improve programmer productivity.
Do not judge me if you have not seen my code.
And I am definitely not someone who just wants to impress with his technical skills. I am a developer because I want to solve the end user’s problem. I actually hate that software development seems to be more about the latest technology (with which the same simple problems are solved again and again) instead of helping the user with their complex functional demands.
But software development is a rich and complex domain, which I wanted to make clear by listing a number of basic concepts that every developer should know, but which (at least in my case) requires some study, thinking and experimentation. This domain cannot be dumbed down so everybody is able to “intuitively” pick it up. That’s like saying you want to be a civil engineer, but you think the math is too difficult, and there are so many machos in the field only showing off their math skills. Every field has an enormous amount of complex things to learn. Software development is not an exception. And yes, there will be exceptions to the rules in almost all languages, and yes, you have to learn these to become a skilled developer.
It is not possible to design a language that works as well for the beginners as for the experts. They have other goals: understanding how programming works and solving complex problems respectively. Look at the evolution of PHP, for example. It started out so lots of people could pick it up quickly, but it has been transformed because more experienced developers need better language constructs to be able to implement their more demanding applications. Does PHP have lots of constructs that will confuse beginning developers? Yes, I am pretty sure it does. Should it return to an earlier language version because of this?
Regarding your other comments. I feel that Kotlin strikes a very nice balance between language features and the level of complexity. Is it a very rich language? Yes, there are many constructs. Will this be a threshold to entry? Yes, there is a lot to learn, not in the least the fact that a lot of design decisions were made because JVM interoperability is considered a top priority. So now you also have to know a lot about Java too.
And removing features used by large groups of developers without problems, because some developers make a mess of it? No thanks, I need powerful constructs so I can remove as much boilerplate as possible. If the team I am working in finds my solutions acceptable, I don’t see any problem with the use of these “confusing” features.
I think a very powerful language design philosophy is Python’s “there should be one, and only one, obvious way to do it”. The same operations should be expressed using the same idioms, language wide. This minimizes the effort needed to understand new and maintain old code. To that end, “foo: $foo” should be the one obvious way to interpolate a string. No redundant constructs should exist by default, which includes overloaded String.plus.
I find it interesting that you propose this specific example. Last time I checked, Python had far more than one way to interpolate a string.
Also, one of the other design principles of Python is “practicality beats purity”, practicality in this case meaning the ease of migration of developers from Java to Kotlin.
To be honest, the whole discussion became a real circlejerk. I have no idea why JetBrains started to design a new language as I have not read up any articles about it. But the fact that it runs on the JVM and is close to Java makes migrating a lot easier, which is probably the reasoning to keep Java functionality alive within Kotlin.
A feature that has been around since probably Java 1 (I started in Java 6, so no idea if this information is correct) has, in my opinion, the right to co-exist with other solutions. Why should people not be able to just concatenate Strings the old Java way with plus? It only works for Strings and no other case whatsoever.
I personally do not see any problem with it. Don’t use it then and move to templates. Done. Let the other people do whatever they want. If they prefer the plus operation, than fine.
In my opinion, Kotlin is a language that puts practicality over purity (as yole mentioned above in the context of python). Is it ok to overload the == operator then for Strings? It’s way more intuitive and easier to just add two things together or compare them using == then using some other construct. And that applies to alot of languages out there.
What I don’t like the most in Python is that philosophy: “There should be one-- and preferably only one --obvious way to do it.”.
I like the Perl and Ruby’s motto more: “There’s more than one way to do it” (TMTOWTD).
Some of Python devs tried to remove map
and filter
functions from the built-in collection library, and tried to remove lambda when they make Python 3 (Weblogs Forum - The fate of reduce() in Python 3000),
saying something like that “there is already the list comprehension in Python, map
and filter
are not needed; there is already def
in Python. Lambda expression is just a shortcut. Everything done with lambda expression also can be done with def
. Lambda expression is not needed.”
Also, one of the several reasons why Python has no switch/case control flow is that.
“There is already if-elif. There is already dictionary. Why do we need switch/case
that can be done with if-elif
?”
Do you like Kotlin without when
control flow because Kotlin have if
-else if
?
Do you want to delete the for
control flow because you can always replace for (i in list) { ...}
by list.forEach { i -> ... }
or vice versa?
Do you want to remove enum
in Kotlin because you can always do the same thing with data classes/objects inheriting from one abstract class even if they are more than ten cases?
I think that philosophy – “There should be one-- and preferably only one --obvious way to do it.” – really hinders Python’s improvement. I mean, not the improvement of the eco-system. The improvement of the language itself. Kotlin should not follow that.