Kotlin lacks the ability to do true functional programming that Swift has. Swift has pattern matching, recursive data structures (edit: specifically ADTs with enums or case classes is what I was thinking of here, should have written algebraic data types), tail call optimization, even some form of type classes, immutability (thanks @tmail21), and so on.
Kotlin does not have any of these (edit: this is now partly false, see below)
I'm sad that Google is supporting Kotlin and not Swift or Scala for Android, since at least with the latter two, you can use functional programming.
Edit: Actually, I'm looking into Kotlin again, and it looks like it's greatly expanded support for functional programming compared to a year or two ago. For example, algebraic data types can now be encoded in a similar manner to Scala, and kind of pseudo-pattern matched using `when`. TCO is now supported. There are lambdas, and support for closures. Destructuring assignment. But as far as I can see, still no immutable values (just immutable references), and no way to make extensible type classes, like in Scala and Swift.
I'm definitely going to take another look now. Last I checked a few years ago, Kotlin had very limited support for functional programming.
And I'm not sure what you mean by recursive data structures. Basically every C style language I'm aware of can contain a reference to another instance of its own type.
It's more java-y than Scala, but it's fundementally capable of a very FP style.
Those are not type-classes, at least not in the Haskell sense. They allow you to avoid an else branch, yes, which is actually quite useful; but one basic ability they're missing is the ability to define a new branch for a new instance of the type defined by library users.
Just as an example. They're really not much like type-classes at all.
I agree with Filligree that sealed classes are not really capable of emulating type classes. They can be used for algebraic data types, which is great, but for true extensible type classes you'd need something like Scala traits.
Tail recursion is a special case of tail calls that can be turned into loops. Their keyword is called tailrec, so it's probably not real TCO. Real tail call optimization can't easily be turned into loops in the general case.
pattern matching: swift has switf and kotlin has when, both are very similar
recursive data structures: I don't get this one, kotlin has all the java api available and all the third party libraries. As java has been here for much longer than swift I guess that swift is lacking more here than kotlin.
Tail call optimization: kotlin has the special word tailrec for this
Yes, kotlin has a lot of things. It also has co-routines like in go, it also compiles to java script and much more.
The reason Google is supporting kotlin and not swift or scaala is because they have to do nothing to support it. Kotlin compiles to bytecode, so it doesnt matter your code is written in java or kotlin because when you compile it it is bytecode at the end. Scala needs to add a runtime when compiling to bytecode, it takes much longer to compile than kotlin and it is not fully compatible with java as kotlin. And Swift it is just something completely different, they should change the virtual machine in order to support it.
Pattern matching: Kotlin has a `when` that desugars into if when statements, but it's pretty far from pattern matching like you see in Scala, Swift, and more traditional functional languages.
Recursive data structures: Yeah, for some reason I wrote recursive data structure when I was thinking of algebraic data types, like Scala can encode with case classes. I often use them in Scala or OCaml to make recursive data structures which is why I mistakenly used that term instead of ADTs.
TCO: glad to see I was wrong. Kotlin added support for this in the past year.
Android: I realize that to support Swift on Android, Google would need to do significant work, but they wouldn't have to change the VM since Swift could also be compiled to Dalvik bytecode. But obviously that would be a lot of work. I only mention Swift since there were rumors in the past that Google was considering fully supporting Swift on Android.
Plus, to be clear, you can run Swift on Android now using the native SDK, just not on Dalvik for making GUI apps.
> Kotlin has a `when` that desugars into if when statements
Actually not. Not now, probably it was the case at the begining of the language.
> algebraic data types
they removed some restriction of sealed classes in 1.1. So I am not sure this is true anymore.
The memory management in Swift is completely different than in Java. That is the main reason you need to make changes in the virtual machine. JVM uses the garbage collector while swift uses reference counter.
> Scala needs to add a runtime when compiling to bytecode
Last time I checked you needed like 500kb of libraries for any scala program compiled to Android. Kotlin is a few kb. Kotlin is a small addition to the java API, Scala needs much more things.
> it is not fully compatible with java as kotlin.
As far as I know, the way scala treats types and functions make it that sometimes you cannot call scala code from java. Well, you can most times but requieres a lot of wrappers. This doesn't happen in kotlin.
I learn scala few years ago, my memory is weak and things may change. But I wanted to use it for android and give up quite quickly because of lot of issues. For kotlin was like love at first sight. No problems at all.
> Last time I checked you needed like 500kb of libraries for any scala program compiled to Android. Kotlin is a few kb.
30kb for Scala is the figure elsewhere in this thread and that sounds a lot more in line with my experience. Note that you never have to use e.g. Scala collections if you don't want to (and thanks to typeclasses you can write elegant code that works with both Scala collections and Java ones, so you can reuse libraries across both).
> As far as I know, the way scala treats types and functions make it that sometimes you cannot call scala code from java. Well, you can most times but requieres a lot of wrappers. This doesn't happen in kotlin.
Nope. There's no difference, just kotlin propaganda.
Well, Google has to do extremely little to support Kotlin, as it runs on the JVM, does so fairly leanly, and does so on Java 6 JVMs.
Swift, they'd have to redo just about their entire stack, as Swift doesn't run on the JVM (Swift can be used with the NDK to build NDK libraries, but it's not standard to build a full app, outside of games, with that).
Scala has had big issues with the size of it's library that still haven't been resolved, and the new versions of Scala require Java 8, which only the beta version of Android supports right now.
What about immutability? A key part of functional programming is using immutable structures to avoid side effects.
My understanding is that Swift has these to some extent ("let" vs "var", structs being immutable etc). And since Kotlin is built on JVM compatibility I _assume_ that Kotlin does not support an immutable style of programming. Maybe someone here has more clarity on this.
> And since Kotlin is built on JVM compatibility I _assume_ that Kotlin does not support an immutable style of programming.
The underlying host doesn't imply anything about language support as that's handled at the compiler level, not at the machine or VM level.
Even in Haskell data isn't immutable if you have a debugger or modify the machine code. It's simply a tool provided and enforced solely by the compiler - other JVM languages do support it like Clojure or Scala.
You can have immutability by making the setters methods of a class private. So if you combine it with "val" you have immutable objects. It is a bit more job in kotlin but as it is also object oriented programming you can achieve exactly what you want.
And for structures you have list, mutablelist, map, mutablemap, etc.
For immutability to be practical one would need to implement structural sharing in their collections otherwise copying would be prohibitively expensive.
I get your point now. Yes, it is read-only, not immutable. For me, I only need read-only. I think kotlin wasn't meant to be pure functional. I see it as object oriented with some functional programming.
out of curiosity, what cases will you use an immutable collection instead of a read-only? I cannot imagine any use case where immutable is a gain over read-only.
"Read-only" would not implement structural sharing.
Consider the situation where you had a linked list with 10,000
elements and you wanted to return a new list with one new element added to the 'head' of the list. With "read-only" you would literally have to make a new linked list with 10,001 elements which would kill performance.
While semantically correct, immutability via deep-copying is very impractical. So, immutability (of Collections in particular) needs to be implemented via structural sharing of elements.
In the above example, with structural sharing, the new list would have the new element and inside would point to the old 10,000 element list but the whole 'structure' would appear to you as just a normal list.
Sorry, I don't see the difference. With read-only you can create a new object which is the first element of the list and also points to the rest of the list. Instead of an structure you have an "immutable" object.
Yes, but the resulting object is not a "List" and hence would not inter-operate with any function that took a List as input.
In essence if the original object implements a List _interface_, then the new one should as well. If you do all of this, then you've essentially implemented immutability and structural sharing. But then you have to do this for 10 other Collection types as well.
Now, you could do all this, but I could do it as well and do it differently. Then my function which took MyList as argument would not interoperate with your function that wants to pass YourList as argument.
Something as fundamental as an (immutable) collection needs to be standardized so that all functions can take these and return them and thus compose easily.
This is the case with languages that implement immutability like Elixir, Haskell etc.
There are already interfaces for Immutable collections in kotlin. And all the functional operators as map, filter, etc, returns them. But it is not true immutability as you said, because under the hood they are normal list. They aren't even read-only objects, but you encapsulate this behaviour under an interface.
This needs to be built into the language or somehow standardized by the community.
With lack of standardization of immutable collections, there would be lots of different ways that libraries would implement immutability. This would result in losing one of the main benefits of functional programming (i.e. awesome composability).
This is already in the language. It is just an interface which makes the common lists only visible as immutable objects. But inside they are a normal list. And in this case the object is read-only, not immutable, as we were discussing in the other comment thread.
> Kotlin lacks the ability to do true functional programming...
Same goes for Swift.
Any "hybrid oo functional" language will not do the functional thing as well as a dedicated functional language. If you're still gluing things together with types, functions will never be quite as first-class as they should be.
Kotlin does not have any of these (edit: this is now partly false, see below)
I'm sad that Google is supporting Kotlin and not Swift or Scala for Android, since at least with the latter two, you can use functional programming.
Edit: Actually, I'm looking into Kotlin again, and it looks like it's greatly expanded support for functional programming compared to a year or two ago. For example, algebraic data types can now be encoded in a similar manner to Scala, and kind of pseudo-pattern matched using `when`. TCO is now supported. There are lambdas, and support for closures. Destructuring assignment. But as far as I can see, still no immutable values (just immutable references), and no way to make extensible type classes, like in Scala and Swift.
I'm definitely going to take another look now. Last I checked a few years ago, Kotlin had very limited support for functional programming.