Kotlin or Swift? (isn't a flame war, its about opinion)

No, I want you to realize that your criticisms are unfounded and your team would get great benefits from Kotlin. I do however want to prevent you from influencing Kotlin design to regress back to antiquated, bad programming practices from the ancient days of programming.

You have a different definition of the word arrogance. Stating facts that disagree with your view of reality does not mean I am arrogant.

Heaven help you there. They do try to support Eclipse but Eclipse sucks so badly that it is probably very difficult. I used Eclipse for years and as I said would never go back to it.

Your statement was that Kotlin is bad because it did “not allow these method two overloads for the same method: fun abc(vararg x: String) and fun abc(x: Array).”. You cannot declare both methods on the same object in Kotlin or Java.

But apparently you were trying to say that you couldn’t pass an array to a vararg function in Kotlin, which is also false. Kotlin jsut requires that you be explicit using the spread operator:

fun abc(vararg x: String) {}

fun foo()
{
    val array = arrayOf("1", "2", "3")
    
    abc("1", "2", "3")
    abc(*array)
    abc("0", *array, "4")
}

The reason you have to be explicit and use the spread operator is to support cases that do not work in Java without a lot of extra work. The last call demonstrates one of those cases that is not possible in Java without manually building another array. Another such case is abc(Object… x) in Java.

I have written more about those cases and the spread operator in another thread so don’t want to repeat all of that here: Pass-through varargs - #9 by dalewking

The reason for pointing it out was more to do with the notion that you are implying that the lack of C for loops might cause Kotlin to die is silly. Even Swift realized that they are a bad thing and unnecessary.

I would have no problem if they deprecated them.

Wow! So you malign a programming practice that you obviously do not understand and you call me arrogant!?

This nonsensical statement is pretty much enough to cause your opinions to be totally discounted. Sure functional programming is not part of most Java programming since you couldn’t actually do it until Java 8. C# programmers are by and large ex-Java programmers or ex-C++ programmers so did not really pick up on FP even though C# supports it (but does not actively promote it like Kotlin does).

Contrary to your statement FP isn’t really taught in college. Some academics got it and only recently has the general public caught on to why it is better. Meanwhile we have decades of non-FP practitioners who think things like the C for loop is a good idea.

But the idea that any program will not benefit from FP concepts is ludicrous. The primary reason that Kotlin is getting so popular on Android is exactly because of its functional programming support since Java 8 wasn’t supported on Android. The fact that you don’t get FP doesn’t mean that it is a bad thing.

Other than being on a standardization committe, the same applies here. I have used many programming languages (e.g. Fortran, Cobol, RPG, Basic, Assembly, C, Modula, C++, Lisp, Prolog, Java, Ruby, Objective-C, C#, Kotlin, Groovy, and enough Javascript to despise it). I have seen enough to know that some programming paradigms are better than others and it is good to have languages that favor the better ones.

Not showing any signs of that. And the things you have mentioned are certainly not reasons it would fail and some like me believe that the things you criticize it for throwing out is part of why it is succeeding.

So if the customer says they want raw pointer access and manual memory allocation and freeiing like we had in C/C++, is that customer right? What if a customer wants checked exceptions which you already acknowledged was a a bad thing and it is good for Kotlin to remove? Should they include every thing any customer would want?

No we have moved on from those antiquated practices and know that leaving them out of the language is a good thing. Similarly modern programming languages recognize that FP is a good thing. Kotlin is pragmatic in that it doesn’t force you to use FP like Erlang does, but it also is not going to go out of its way to help you avoid FP. A large number of programmers think that is a good thing, not something that will kill Kotlin.

3 Likes

@DonWills: You seem to be looking for a language that Kotlin is not. Even better: You are the decision maker, so simply decide to not use it. In your case, nobody is forcing you to use Kotlin if you do not like it. There are tons of other languages to choose from. Follow Hacker News, new languages/dialects are announced regularly.

The reason why you get such push back is that a lot of people (including me) chose Kotlin specifically for its opinionated way of doing things. They (possibly incorrectly) think that this will make their code shorter, better to understand, safer and more robust.

And instead of continuing to do things like they were used to, they studied the concepts behind and the features of Kotlin, and wrote their code to align with it. That does mean that in some cases you don’t get extremely terse code, but you do get the safety that Kotlin offers.

So please stop asking for Kotlin to be changed to a language it was never intended to be. If you face issues with Kotlin, ask questions, and we will tell you how to solve a particular problem in Kotlin. If it turns out that you don’t like a lot of the answers, I advise you to look further.

3 Likes

@jstuyts: By exactly the same logic, you’re very much free to use the current version of Kotlin, if you like it so much. The designers have committed to maintaining backwards compatibility, so no change will affect you, if you don’t want it to. The general level of push back thus makes no sense at all and is just a waste of energy on everyone’s part.

@dalewking: You definitely come across as very arrogant. According to you, everything that comes out of your mouth is nothing less than facts, and everything that disagrees with your “facts” is … let’s see, just from this thread: false, baffling, masochistic, dangerous, irrelevant, horrible, bad, ugly, antiquated, unfounded, sucks, silly, malignant, nonsense, ludicrous. I’m sure I missed a few, but I doubt you’ll catch my drift anyway, so if you’d like a 100% complete list, do it yourself :stuck_out_tongue:

Also, Javascript does have static.

1 Like

There’s @libgdx at kotlin slack, who knows a lot about java game eneinges, and there are people who are experimenting with kotlin games on #gamedev channel.

2 Likes

This is my interpretation of what you are saying above. Correct me if I am wrong: Kotlin is guaranteed to be backwards compatible, so any feature can be added without problem. Even features that violate the principles that Kotlin was based upon. One can simply decide not to use it.

I cannot disagree with that.

All I am trying to say is: Every language choice comes with trade-offs. In the case of Don and you, you are both dissatisfied with the features of Kotlin, and the “rigidity” of the team and community.

What features of Kotlin attract you so much that you do not want to use one of the many other languages? Groovy might be interesting to Don. In your case, you are probably better of with a lower-level language.

Not sure what principles you’re referring to, but if you mean “Concise, Safe, Interoperable, Tool-friendly”, I love and support all of those and wouldn’t want to “violate” them…

There’s plenty of things I like about Kotlin, in fact going through the menu on the left here, I like (and use) pretty much all of them.

The few things I’m complaining about are just things I hit many times daily, and which don’t actually support those four principles, even if they were intended to do so. And I find Kotlin not to be very refactoring friendly…

The top of the list is definitely that Smart cast to ‘X’ is impossible, because ‘y’ is a mutable property that could have been changed by this time… I’m pretty sure I’ll never get co-workers to switch to Kotlin until it goes away, the error is really “WTF is wrong with you, compiler, I thought you were here to help me, not be a smart-ass?!?”… And it doesn’t seem to get better with time - even though I’m used to it by now, I still hate it every single occurrence :slight_smile:

(and again, I totally like compile-time guarantees, I use code analysis tools and all that, but this is something that’s a false positive at least 99.99% of time and there’s no way to turn it off)

To paraphrase Ruby Rhod, I don’t want one level, I want all levels :slight_smile: I really like D in that respect, it goes all the way from assembler to advanced meta-programming, and you can solve each problem at the level that fits it naturally… Alas, one doesn’t work alone on most paid-for projects, and it seems quite a lot of experience is needed before people can use such a rich tool effectively…

1 Like

I think the discussion is quite useless since it is mostly based on opinion and preferred programming style. I can’t agree with most arguments presented by @DonWills. Companion objects and spread operator are some features that need some time to adapt, but in the end, all these features make language better, not worse.

But I wanted to talk about another thing. The problem is that one can’t create a language to suite everyone. And Kotlin has a mechanism to adjust the language for personal needs: compiler plugins. If one needs something better for himself, and specifically if that someone claims to have a lot of compiler development experience, he can just write his own compiler plugin to adjust language to specific needs. If he ends up as the only one using this plugin, everything is obvious. If it is popular, it is possible that mainstream vector could be changed to accommodate for community needs. The same goes for Eclipse plugin. If community needs some tools like eclipse plugin, why not start working on it?

2 Likes

I actually took a look at that option, and as far as I can tell, this line is the culprit and there’s no hook for the plugin to override anything here:

If I’m wrong, please point me in the right direction and I’d be most definitely very happy to take the time and create the plugin…

Technically the compiler is 100% correct. It cannot know how this code will be used, and if it is used in a particular way there is a chance that the value may become null.

I don’t see why it wouldn’t be possible to tell the compiler you know it will never be null. As long as it is explicit that you made that choice.

That sounds like a good feature request/contribution. And in the worst case a fork: Forklin :wink:

Yes, it cannot know, so it makes an assumption that it will change. Given that assumption, I agree that it’s 100% correct. But the assumption itself is what is wrong 99.99% of the time, and so then is the overall result.

1 Like

If there is a very common use case, like only single-threaded use of an object, I am sure people are open to a new language construct. But it has to be done right. How can Kotlin detect that you did not use the object in a single thread (without having too large of an impact on the performance)? I have not explored whether or not there is such a way, I am only indicating that any new language construct must provide the same safety as existing features. The impact of that safety may be too high for inclusion in the language.

If you want to get rid of the safety completely in the above case, I would suggest to name the keyword/annotation “all bets are off” :wink:

thanks, I’ll look at the slack channel

This error does not provide any safety in the sense of “follow the rules and your code will work”… That’s why I’m complaining - in return for making all code using vars ugly you only get an illusion of safety, while the code is correct or not correct regardless of this error. I’ve been thinking about this for many hours, and I still haven’t managed to come up with a realistic example where merely working around this error (using ?.let or whatever) will make the code work correctly, where it previously didn’t.

Maybe it’s just my lack of imagination… So far, however, nobody has provided an example of code where this error directly helps turn incorrect code into correct code, without any locks or other sync primitives. Even the trivial

if (field != null)
   field.someMethod();
// while another thread furiously writes to field

does not become correct just by doing

field?.someMethod();
// while another thread furiously writes to field

because without any synchronization step (lock, volatile, atomic, whatever), the furious writes by the second thread can be completely invisible to the first thread, in theory forever. To be honest, I’d strongly prefer to see exceptions in that case (if I was lucky enough to see them happen), compared to the incorrectness being swept under the rug…

Well, I’ve proposed a big and direct @AssumeSimpleVarsAreStable, but nobody seems to like it :-/

1 Like

it is possible. That’s what !! operator does. It tells the compiler you want the compiler to assume it is not null. Any NPE after that point is your fault.

1 Like

I don’t think the point of the error is to say that adding ? will make the code “correct”. When it is a local val the compiler can guarantee that it is correct and nothing can change it. The error is saying that the compiler cannot make any guarantees and you need to handle something to make sure it is correct. In some cases ? is enough in other cases you need synchronizzation, etc.

And quickly on previous post, strongly opinionated based on experience != arrogance, but I really don’t want to argue about personalities and would prefer discussions like jsuyts said:

The compiler can’t guarantee much of anything, and so what? This error is actively making code worse for no benefit (an example here), so it’s a bad idea.

Consider this parallel world, where you couldn’t write

println(2 + 3) // ERROR: function call could produce a StackOverflowError

Then you’d have to write something useless to make the compiler happy

@DangerouslyAllowFunctionCallsUsingStack
expectEnoughStackSpace!(println)(2 + 3)
// now we guarantee not to throw StackOverflowError, but well, we might throw KotlinStackOverflowException("println")

And then when someone complained how annoying that is, I guess one of the response could be saying something like:

I don’t think the point of the error is to say that adding expectEnoughStackSpace! will make the code “correct”. When you don’t call any functions, the compiler can guarantee that stack overflow will not occur. The error is saying that the compiler cannot make any guarantees and you need to handle something to make sure it is correct. In some cases expectEnoughStackSpace! is enough in other cases you need to tune JVM parameters, etc.

1 Like

It seems like the discussions have gotten off topic. The original question asked for help with choosing between Kotlin or Swift. Since we’re not comparing against Java, I recommend phrasing what you dislike about Kotlin in a way that compares against Swift since these are the only 2 options being considered by the original request.

While I struggled to like some concepts initially, I actually started to appreciate them after some use as my original dislikes were caused because I was thinking in a different mindset that I had become accustomed to over the years. So I really enjoy the new mindset.

Personally, I chose Kotlin over Swift for the following reasons:

  1. I can leverage existing investments in Java (eg. can use existing open-source Java libraries)
  2. I can transition a large project from Java to Kotlin without requiring us to re-write everything
  3. My skills will become more valuable since Kotlin can be used in many scenarios (eg. server-side, Android, javascript, native)
  4. Productivity improvements. We all agree that having a higher typing speed doesn’t have a measurable effect on time to market. Time spent fixing defects is by far the largest investment as projects mature over time so I really appreciate the fact that Kotlin helps avoid entire classes of defects.
  5. I really enjoy Kotlin DSLs as I use them to enforce patterns resulting in even fewer defects.

So it’s true that Kotlin isn’t perfect but it seems like it’s the best available option for me personally so I hope this helps to answer the original question.

2 Likes

There is actually a really big misconception here: compiler plugins are not a way to adjust the language for personal needs. Neither in their current implementation, which is intentionally undocumented and supports only the specific use cases that we’ve encountered so far, nor in their potential future evolution. Compiler plugins exist to support use cases that cannot be supported well enough using the core language, and not to allow users to change the design decisions in the core of the language

I agree that the assumption is often wrong (although it does assume that there is no threading issue nor any reentrance issue). The introduction of a local variable is however not a bad idea (and I think that it should be possible to provide a quick fix for this - and it should be provided). A local variable copy will also make the field access local making the second access cheaper (as the language is required to evaluate the value (or getter) again in the non-local case). JIT compilation may or may not be able to elide the reevaluation, but having a local means that the JIT doesn’t need to try to proof that it is valid (no side-effects, nor possible value changes).

I believe he’s referring to (::fooFunction) vs. { it.fooFunction() }

To be fair, he was just clarifying a comment he made (“Kotlin has more warts than Java,” to paraphrase) specifically because I asked him to. And I asked him to because as much as I love Kotlin, I don’t want to be one of those people who drink the Kool-aid. I want to hear concerns from people more critical than me, because they might be right. At the very least, I can evaluate whether those concerns are valid and relevant for me.