4 ms·
Kotlin is a fine middle ground. I would say that coroutines was a misstep (though that's a matter of taste), but otherwise their choices have been pragmatic, an
by smallerfish 4y ago
Kotlin is a fine middle ground. I would say that coroutines was a misstep (though that's a matter of taste), but otherwise their choices have been pragmatic, and their multiplatform efforts are impressive.
- matsemann 4y agoYeah, the interop makes Kotlin also a hundred times easier to test out. No changes to setup or tooling, just drop a few lines in your pom.xml and you're good to go. But curious, what's wrong with the coroutines? For some projects I've found them a nice abstraction when you have lots of IO-bound tasks, and they're bound at various places in the code making use of a single executor+threads/tasks hard to scale.
- smallerfish 4y ago> But curious, what's wrong with the coroutines? Maybe I need to revisit them, as I've only used them (on 1.6) in the context of kotlinjs (which has a limited implementation) so perhaps my impression is flawed. That said, I didn't like how viral they are in the codebase. In an executor/thread paradigm, you can box up the asynchronous behavior quite cleanly; in a codebase that uses coroutines, I ended up propagating `suspend fun` up and back in my codebase.
- matsemann 4y agoAh, yes. The "which color is your function" is a bit problematic, but nothing inherit to Kotlin's approach I feel. I'm having the same issues in an asyncio python project now, for instance.
- dionian 4y agoI drop scala into old maven projects all the time by dropping in the scala maven plugin
- MrBuddyCasino 4y agoThey have to be careful, there are tendencies to over-complicate things as well. I hope coroutines will die on the serve side once JVM Fibers are widely available.
- ragnese 4y agoCoroutines for async IO will hopefully die, but right now coroutines are the best way to implement continuations, so I hope they just become a niche feature for library authors to do things like monad comprehensions, etc. I can also imagine nice DSL-ish APIs for things like SQL transactions, where you can call "rollback()" to abort the transaction inside a closure, instead of throwing an exception and catch-swallowing it.
- billfruit 4y agoIs Kotlin too much tied to maven? Can someone be productive with having to do maven hair splitting.
- ragnese 4y agoI disagree. Obviously, this is all just subjective preference and opinion, so parent should not take this as me saying they're wrong. I hate Kotlin's "middle ground" approach. Scala has persistent data structures for collections, which means that non-destructive updates and copies are cheap. This is great for an immutable-first approach. Kotlin uses Java's mutable collections, so all of the standard APIs in Kotlin make full copies. Sometimes it might even be surprising where copies are made. For example: `listOf(1, 2, 3).toList()` makes a copy of the list instead of just returning it. To understand why this is necessary, see my next point. Scala's mutable collections are NOT sub-types of its immutable collections. In Kotlin, there is no such thing as an immutable collection interface. You have MutableList and List, but despite the confusing naming, List is NOT immutable because MutableList is a sub-type of List. So any time you write a function that takes a List parameter, you can't assume that it's not actually being mutated from another thread while your function is running. That means that you technically can't even assume a List is non-empty after you check `if (l.isNotEmpty()) { useElement(l[0]) /* this might crash */ }`. So Kotlin's middle ground approach means that it's inefficient to use the pseudo-functional APIs and its collection types are not concurrency-safe. Then, there's no error handling mechanism in the language. Well, there's throwing unchecked exceptions. But the Kotlin team tells you not to do that. They tell you not to do that, but that's actually the only thing that is done in the standard library, the kotlinx.libraries, and every single thing that IntelliJ actually publishes. So, it's very "do as I say" with no examples. At least in Scala we have Try, Either, and "for-comprehensions" (a.k.a. monad comprehension, do-notation, etc). Kotlin "recommends" we use sum types to express failures, but without monad comprehensions, it's extremely awkward and verbose, so I've literally never encountered a Kotlin library in the wild that does anything but throw exceptions for business logic failures. I strongly believe that it was precisely to avoid scaring off Java devs that they didn't do do-notation and monadic error handling. I don't mind colored functions. I do absolutely HATE that Kotlin coroutines use exceptions for control flow and business logic. It's so hard to correctly handle sub-jobs in coroutines in any non-trivial case with cancellations, etc. They also decided to not do type-classes, so we get half-baked, ad-hoc, cherry-picked type-class-like features such as extension functions and multi-receivers. I especially dislike extension functions because the receiver is resolved statically (it has to because of how it works under the hood), which is NOT the way regular method calls work, which adds yet another inconsistency to the language that's impossible to catch at compile time. Ugh. And I'm working on Kotlin code today, so now I've got myself all upset about it. lol.