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


#1

I’m now considering in building a game engine from scratch (yeah plan to use some libraries, but almost all from scratch), first of all I want to build it for fun and b/c I like to build one, so the discussion here is, use kotlin or swift, why those languages? b/c I consider them fun and like to play whit them.

Then why I’ve not chose one? b/c I like a language that runs without a VM (yes, kotlin native, its on early stages but may be released when I finish the game engine, but I find hard and unpleasant to work right now with it, b/c IDEA doesn’t support right now it out of the box and its quite annoying.

So I want to hear suggestions about it, also I’ve tested lwjgl (thinking later on I could replace with konan OpenGL/GLEW binding) but I’m not sure which one to pick right now.

Regards


#2

Don’t know much about Swift, so can’t help with the question from the title, but D and Nim might be worth looking into for a game engine project… IMHO, Kotlin is too high level and patronizing for a (decent) game engine…


#3

Well you can say the same about Java and indeed theres tons of games build on top of it (yeah mostly Android games), but I will not build an AAA game that need to be optimized to use all the resources in the most optimized way.

Also I read about it and if will choose another language Rust will be better (some ppl claim that its the “new C”). But I don’t want to learn a new language that doesn’t have much field out there (about jobs), but with Kotlin and Swift theres a tons of jobs, so I want to stay with one of those two, about performance I think Konan in the future will have better performance that the JVM counterpart, b/c if I’m not mistaken is using llvm to compile the code, so will not be far from swift and other mid, hight level lang performance.


#4

I’m pretty sure that if you make a usable game engine, you will not have trouble finding a job, regardless of the language it’s written in, because learning the programming language is by far the easiest part of the whole thing (come to think of it, that’s probably true for almost any type of project). But I still wouldn’t pick Kotlin, because it has a strong bias against mutable state, and games are all about mutable state (i.e. stuff tends to move and/or do other interesting things).

Of course I know nothing about your life situation at all, so it may well be that Kotlin is the best choice, all other things considered… Usage of grains of salt is highly advised :slight_smile:


#5

Three years ago, I was hoping that Swift would become the new lingua franca of the programming world. So I spent a year learning and building real applications. I was very disappointed, and not just because Swift was/is a moving target - Swift really feels like it’s just a random mixture of ivory tower concepts mixed together with an Objective-C flavor using a Java-like syntax (things like ARC and Swift’s ridiculous String handling are real concerns).

IMO, Kotlin, with all its warts, is a better programming language than Swift. That said, I was hoping Kotlin would be a better programming language than Java. It’s not - Kotlin just trades some Java warts for new ones. The key interest in Kotlin for me is the JS and Native targets that Kotlin promises to support. When Kotlin for all three of its targets - JVM, JS and Native - becomes more mature, I believe Kotlin usage will grow. I doubt that Swift will ever make a significant dent outside of the Apple ecosystem.

So norman784, the answer really depends on what your subjective concerns are, and what targets you plan to support. Is portability between iOS and Android important? If so, Kotlin is better for you, but only when/if Kotlin/iOS support becomes viable. Otherwise, Kotlin and Swift aren’t all that much different syntactically or practically.


#6

Indeed, I’m a mobile developer, and at this point don’t want to learn another new language, also C and C++ are not an option, or another mainstream language like D, Rust, Nim, etc (I started reading the Rust doc and I quite don’t like it, the syntax, over Kotlin and Swift).

The think here is, if I started writing more than mobile apps with one of those languages in the long run I’ll learn how to better coding with them and their deep tricks, I’ve 2 years of experience in Swift and I could say that I don’t master the language, I could write apps without any issues but always theres some advanced things that you could do with more understanding of the language.

I’m not interested in write a game engine in Kotlin JVM, but in Konan (Kotlin Native, think is their internal name or something), b/c you know I’m not a fan of Java, and also don’t like too much JVM, but I need to thanks Google for introduce Kotlin in Android.

More over, I will look forward for the new releases of Konan and hope the IDE support comes sooner than later.

Thanks all for the reply.


#7

That said, I was hoping Kotlin would be a better programming language than Java. It’s not - Kotlin just trades some Java warts for new ones.

I would love to see a thread in which you elaborate on this.


#8

I have several criticisms of Kotlin. Here’s a random sample.

Array handling is inferior to Java in several ways. One is a performance concern - in Kotlin/JVM, a method call needs to be made to access or mutate an element, not so in Java. The lack of static fields and methods is a giant mistake. The requirement for “var” vs “val” is a huge annoyance. Having multiple syntaxes for specifying lambdas is another bad decision. “lateinit” is ugly and really doesn’t accomplish anything positive - it just fixes an issue with Optional that should not exist (see one of my comments below). In short, specifying nullability should be optional, not required. I truly dislike opinionated programming languages, which seem to be all the rage today. Kotlin and Swift are far too opinionated for my taste.

The cost of maintenance of big systems is my number one concern and in that regard Kotlin doesn’t seem to me to be any better than Java. Compile times are worse. Tooling is worse. For Kotlin to succeed, it needs to be superior to Java, not just similar.

Here are 4 items that I’ve posted here. The comment threads on these posts are enlightening about the mindset of the language designers with respect to the concept of “pragmatic”.

“platform types” (the Kotlin name for the Java not doing null checking on call) should be an available to Kotlin programmers. Read the comment thread here -

One more thing - IMO, Kotlin could become a much better language if it included some sort of fixed decimal arithmetic. But that does not seem to be in the list of planned features.


#9

Indeed, theres some odd thinks about Kotlin, and also thats why I want to write something at low level, b/c I didn’t notice some things that you mention there, I’ve been playing with Kotlin just 4 months ago, theres some things I love from Kotlin and others from Swift.

Yes, the build times are slower comparing to Java, but I think they are solving some of those issues with the 1.2 (think its in beta right now), but give it time, now with the Android adoption their evolution may be faster, I started with Swift 1.2 or something like that and at that time it has also so many flaws, but now the language its much solid.

Off topic: Also I dream the day when I could truly share my code between iOS and Android (I tried Xamarin but I didn’t recommend, its a real pain).


#10

From Kotlin side Array is a class and accessing its elements looks like calling methods. Perhaps this makes you think that Array is really translated to some hidden class in JVM with methods to access elements. In fact, Kotlin compiler intrinsifies everything related to Array class, as well as IntArray, LongArray, etc. For example, let’s compile following function in Kotlin:

    fun foo(arr: Array<String>) {
        println(arr[0])
    }

and watch the generated bytecode:

  public final foo([Ljava/lang/String;)V  // function takes String[]
    // null check
    ALOAD 1
    LDC "arr"
    INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull (Ljava/lang/Object;Ljava/lang/String;)V

    // access to 0-th element
    ALOAD 1
    ICONST_0
    AALOAD
    ASTORE 2

    // print it
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    ALOAD 2
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/Object;)V

    RETURN

Except for call that checks whether arr is not null, javac would generate the similar bytecode for corresponding Java code.


#11

Actually, Java version is quite a bit simpler:

       0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: aload_1
       4: iconst_0
       5: aaload
       6: invokevirtual #3                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       9: return

Why does Kotlin compiler introduce that local variable, it seems quite unneccesary?


#12

Local variable is introduced because println in an inline function you can “step into”, so the local variable allows to preserve the illusion of a separate function for debugging purposes. Whether it is strictly needed is an open question.


#13

Others have already addressed your false criticism on Arrays.

Java forces you to add lots of boilerplate to not expose raw fields and makes you use completely different syntax for accessing raw fields from using getter/setter… Kotlin does what you want 99.9% of the time and creates the getters and setters for you and lets you use syntax that treats it as a property.

If you really want to avoid the getter/setter method overhead you can inline getter and setter (which only affects calls from Kotlin) or you can annotate the property as @JvmField and you have exactly what you have in Java.

Kotlin on the JVM supports static fields and methods:

class Foo
{
    companion object
    {
         @JvmField var staticVariable = 5
         @JvmStatic fun baz() { println("I'm a static method"} }
    }
}

They are not part of the language because they are specific to the JVM. They would not make sense in Javascript.

That opinion is baffling to me. You somehow prefer having to explicitly specify a long type instead of letting the compiler use implicit typing? And you think the final keyword is better than simply changing one letter to go from var to val?

What multiple syntaxes? There is one syntax that is used for lambdas. There are anonymous functions that are like lambdas, but are only needed in the rare cases where you need to explicitly specify the return type

Definitely disagree with you on that one (although would not be opposed to ! as an alternative to lateinit) which makes no sense given your later comment:

NPE is a huge maintenance issue. Kotlin actually addressing that and making you be explicit about nullability is a very good thing.

Agreed that it is slightly worse, but that gap keeps narrowing very quickly since the language company and the tooling company are one and the same (unless you are a masochist and still live in Eclipse). Any deficiencies here are more than offset by development improvements from the language.

Would be a welcome feature, but not absolutely vital feature. Java has been quite successful without it and Javascript is even worse that Java.


#14

I need to explain this sentence for readers to understand my concerns:

Kotlin and Swift are far too opinionated for my taste.

IMO, many programming language features should be optional. In other words, not required. In far too many cases, programming language designers have decided that features are required because the designers know better than you what’s good for you. I reject such thinking.

For example, after years of suffering with checked exceptions that Java programming language designers had decided was a ‘good thing’, C# made exception declarations on methods optional (ie. ‘unchecked’). Since then, most new programming languages having either omitted exception declarations completely, or have followed the lead of C#. It was the opinion of the Java designers that caused checked exceptions to be implemented in the first place - that forcing programmers to declare their exceptions would make the resulting systems less buggy. However, the reality is that it didn’t make much difference. That is, their opinion was wrong. The result was that there were real costs to programmers that didn’t do much to help fix the perceived issue. That’s an example of what I mean by ‘opinionated language’.

The designers of Kotlin did good by removing certain required elements of Java. For example, by removing the requirement for semi-colons, by allowing the var keyword when the type can be inferred on declarations, by removing checked exceptions, and by removing a few other syntax elements that are today referred to as “boilerplate”.

However, the designers and implementors of Kotlin made several poor decisions because of what I perceive as their opinions of what is a ‘good thing’ that programmers must be required to adhere to.

Example 1. Nullability declarations. Why can’t programmers have the option of not using the feature, instead of being required to use it. By simply adding the concept of “platform type” as a declaration option, then programmers could use the nullability declaration where appropriate, but are not required to if they don’t want to.

Example 2. Static fields and methods in classes. I perceive that Kotlin designers have the opinion that the concept of “static” is bad, and thus it was omitted from the language. I wrote at length about this issue in a thread referenced above. And no, the suggested solution with @JVM… annotations is not useful for writing portable code, because it is not part of the Kotlin language and thus (I assume) won’t be supported in Kotlin/JS and Kotlin/Native.

Example 3. The compiler warning about ‘var’ vs ‘val’. I realize that this is not a language specification issue per se, but please, will the compiler implementors make a special switch to turn this one warning off? Some warnings are very helpful. This one is really annoying, particularly during initial development.

Example 4. The language does not allow these method two overloads for the same method: fun abc(vararg x: String) and fun abc(x: Array<String>). Why? I suspect it was the opinion of the Kotlin designers that this is not a ‘good thing’, therefore it could be omitted. This is just one element of my dislike of the design of Array in Kotlin.

Example 5. C-style for loops were removed. Why?

There are several more examples of what I call ‘language designer opinions’ that are requirements and that I disagree with. Readers might find this article enlightening: https://kukuruku.co/post/why-kotlin-sucks/.

That said, IMO, Kotlin is still much better than Swift. I just wish it was better than Java.


#15

Don’t bother @DonWills… The response to “X is bad” is invariably “no, X is good for you, and you can and should use this verbose, ugly, inefficient and/or confusing workaround all the time”. The response to “It’d be good if X was added” is invariably “no, X is bad, and besides, you can already do it in this verbose, ugly, inefficient and/or confusing way”. Or, you’re simply ignored until you go away :slight_smile:


#16

And I reject that rejection. There are things that we know are better. C/C++ had raw pointers and manual memory allocation. The designers of modern languages do know better and recognize that these features are dangerous and forbid them, not just making the optional. If you make them optional they will still get used.

Irrelevent example ignored

It is optional in that if you want to stay in the dangerous world of rampant NPEs you can declare all properties as Nullable and use !! all over the place. Is that painful? Yes, it was meant to be and that is a good thing.

Static is not portable. Javascript does not have static, but you can have the concept of a companion object. In terms of native there is no benefit for static vs. companion objects for native. They use companion objects because that is what is portable. The only place where static is an issue is in compatibility with Java and the @Jvm annotations handles that just fine.

What warning?

Well it isn’t allowed in Java either because both have the same signature. Feel free to try compiling this in Java:

public class Foo
{
    void abc(String... x) { }
    void abc(String[] x) { }
}

Kotlin has some specific improvements over Java here. First it has the spread operator to actually be able to handle some cases of passing the content of arrays that cannot be done in Java. Secondly, it actually will let you define both methods by renaming them on the Java side:

class Foo
{
    @JvmName("abcArray") fun abc(vararg x: String)
    {
    }

    internal fun abc(x: Array<String>)
    {
    }
}

On the Kotlin side the method is just called abc. If calling from Java you have to call abc or abcArray which is actually no different since you couldn’t have defined both in Java any way.

Because they are horrible. They are hard to read and encourage mutable state (which is another of those things they made harder) and there are better alternatives in Kotlin.

That style of iteration is called external iteration and for most cases you can do it cleaner with something like this:

    for(i in 0 until count) { }
    for(i in 1 .. 10) { }

But in a language that actually supports functional programming there are much better choices using internal iterators as in:

    (1 .. 10).forEach {  }
    values.map(it.foo).filter { it.bar > 5 }.forEach{ }

For a good lesson in this see this talk (which is actually for Java 8) by the ever entertaining Venkat Subramaniam: https://www.youtube.com/watch?v=Gsfmfeb2XW8

And if you read the comments I have already responded to that article a long time ago. As shown again here, just because some one posts something on the internet does not mean they are right.


#17

dalewking - most of your comment just reinforces my disdain of such arrogance that you defend.

Here are comments on a couple of your points.

In response to my example 3, you write “what warning?”. Answer: the warning you get when you declare a var and then don’t modify it.

With respect to the Array overload issue, in Java the void abc(String… x) { } method subsumes the void abc(String[ ] x) { } method, thus I can provide an API to consumers that offers both overloads in Java that is not possible in Kotlin.

With respect to statics, you write “Static is not portable.” Of course static properties and methods can be portable in Kotlin. It might take a bit of compiler magic, but it can be portable. I don’t care about interoperability with any target - I just need the feature. And no, companion objects are not a complete replacement for Java statics. Java, C# and Swift all have statics, why doesn’t Kotlin? I believe the real reason for no statics in Kotlin is the ‘its not good for you’ meme.

One of the lessons that language designers seem to either not understand or don’t care about is that a new programming language becomes irrelevant if it is not adopted by a critical mass of programmers within a few years. And that many of the decisions made by the language designers strongly affect adoption. I had hoped that Swift would be a language to take the place in the world of applications that Java and C# dominate. It won’t. I also hope that Kotlin might be the language to replace Java and C#. In its current form, it won’t. The only real advantage that Kotlin has compared with Java is the Kotlin/JS and Kotlin/Native targets. Microsoft has recognized this limitation of Java, and bought RoboVM to kill it and then bought Xamarin to kill its Java tools and provide only C# tools, and to then provide Android and iOS targets to further its programming language hegemony with C#. Thus Kotlin’s advantage of 3 targets will likely quickly be gone. Because of this, the future of Kotlin is not assured.

FWIW, folks like me make decisions about languages. I own a 90 person software company (~50 are programmers) that is looking to move to a new development environment. For my company to chose Kotlin, proponents need to prove to me and my company on why Kotlin is good and will be successful instead of telling me that I’m wrong. Don’t tell me that I don’t need optional Optionals because they are bad for me, or that I can’t have traditional for loops because they are bad for me, yada yada yada. So far in our first year of Kotlin exploration, none of my concerns about Kotlin appear to be showstoppers by themselves (except for support in Eclipse and the question of long-term success), but taken together, the volume of issues may make the difference between our adoption of Kotlin vs the competition.


#18

@DonWills @dalewking Just want to clarify about statics: static members in Kotlin classes were one of the future features proposed, see the feature #17 in this survey. So this can be taken as some evidence of that Kotlin team considers statics at least not that impossible. :wink:

Interesting that this feature also was one of the controversial ones, it received a lot of votes for and against it.


#19

If you are using idea then it is easy to disable any warning. But the preferred method is to declare everything as val unless you absolutely need to modify it. There are advantages to vals over vars. The “why kotlin sucks” article mainly suffered from the author wanting everything to be a var.

Realize that in a functional programming world if you are modifying a field you are probably doing it wrong, but that will just be seen as me forcing better practices on you.

Not sure what you mean by “subsumes”, but you cannot have a class that declares both signatures, so your statement is false.

And other than backwards compatibility you have still not provided any reasoning why statics are better than companion objects? Just because another language had something does not mean all other languages should. I forgot also that package level functions and properties also fulfill much of the role of statics and actually generate statics. I still have not heard why you cannot write software because Kotlin has companion objects and top level properties and functions instead of static.

By the way you might be interested in a recent Fragmented podcast that discussed this very topic: http://fragmentedpodcast.com/episodes/92/

Luckily, Kotlin designers made the right decision and it is being adopted on the Android side in droves: https://www.bleepingcomputer.com/news/mobile/kotlin-expected-to-surpass-java-as-android-default-programming-language-for-apps/

On the server side I am not sure there is any thing that would move the needle away from Java. My feeling is that is because not that much new development is happening there and most of the code is legacy code.

I think any one doing Kotlin would disagree with that.

I have done Xamarin, Java, and Kotlin and would take Kotlin any day of the week.

Sounds like a bad plan to me. Have your developers try it and get their feedback.

So you were arguing that Kotlin enforcing nullability was a bad thing and now you are demanding Optionals? The problem with Optional is overhead since it creates an object, although technically I suppose the compiler could optimize that away, but I fail to see how that has major advantages over nullability in the type system.

And why do you need the old ugly for loops from C. What problem cannot be solved with the many better alternatives in Kotlin. There has been some new innovations in the past 45 years since C was introduced and this antiquated construct just is not needed…

I also point out that Swift originally had C style for loops, but removed them in Swift 3.0. The discussions here about that also generally apply to Kotlin.

Certainly you are going to struggle if you are still using Eclipse. You have my sympathy, but I would strongly recommend moving to idea. Frankly you could not pay me enough money to go back to Eclipse.


#20

dalewking - Wow! Are you trying to single-handidly make me decide against Kotlin? Your arrogance is amazing. If you are in any way representative of the thinking of Kotlin designers, then I sincerely doubt that my company will consider Kotlin after one of my company’s senior employees and I attend the Kotlin Conference in 2 weeks.

I don’t use IDEA and I don’t want to force my programmers to use only one IDE. And FWIW, on the kotlinc command line help message, I only see one option for disabling ALL warnings: -nowarn.

Many of my company’s programmers already use Eclipse in different programming languages. It works great. As I said, if the Kotlin Eclipse plug-in doesn’t get working well in the next few months, none of these other concerns are relevant - that will be a deal-breaker for us.

Nope. My statement is true. I only declare ONE METHOD in Java - void abc(String… x) { } - and call sites in Java can use either multiple Strings or an array of Strings. It’s been that way in Java for many releases.

Your suggestion that because the designers of Swift threw away old ugly for loops (your words), that it was a good thing and justifies that Kotlin it did too. Swift also tossed out ++ and --. Why didn’t Kotlin toss them out too?

And, no, I have no interest in forcing Functional Programming onto my company’s code base. Functional Programming is simply a fetish created by ivory tower philosophers and taught to innocent minds in college. It is almost completely divorced from the real world. FP might be slightly useful for certain algorithms in multi-threaded programs, but is much more of a hindrance than benefit for writing the type of business applications that are the bread and butter of Java and C#.

I am a developer. I’ve been doing programming for decades. Although I don’t participate in day-to-day operations of my company any more, I am heavily involved with the company’s technical decisions. Programming languages and the process of building application systems is very important to us. And portability is extraordinarily important to us for a variety of reasons that I won’t elucidate here.

One of my senior programmers (not the one coming with me to the conference) and I have been working with Kotlin for months. We’ve got a very sophisticated business application to run in 4 combinations: Java with Java FX for desktops, Java with Android, Kotlin with Java FX for desktops and Kotlin with Android. We are comparing the results and experience. Kotlin development was painful although I attribute some of that to our learning curve.

I grok programming languages. I’ve written compilers, interpreters, was a member of an ANSI standardization committee for a programming language, and I’ve programmed in and I understand more than a dozen programming languages. I’ve seen many languages like Kotlin come and go, withering away to mere anecdotes in the history of computing. That’s what I really fear the most in Kotlin - that Kotlin will fail for whatever reason. One of the reasons might be that there are enough organizations like mine that will decide against Kotlin because even though Kotlin designers call the language pragmatic and have gone to great length to be interoperable with Java, they tossed out tried and true language elements because the Kotlin language designers didn’t like them. The customer is always right is not a throwaway concept - it is everything. And I am a potential customer.