Kotlin backend dev of 7 years here (never done Android). Here my 50 cents to some of the "bad" points:
1) tenary operator. Apart from the "if-else is an expression" defence there's also the fact the in Kotlin the '?' is linked to nullability, not only conceptually but also in regards to parsing Kotlin code. There's a video on youtube where the first Kotlin language designer said that he once - because so many people were asking for it - actually sat down and tried to my the "a ? b : c" syntax work, but couldn't because of ambiguity (I think the issue was interaction with nullability operators, but I could be wrong).
2) return inside lambda. There is actually an option that allows for normal returns, but it's not very idiomatic (to a degree where I myself forgot that this option exists until a few months ago) and that is to instead of providing a lambda as a parameter, you can always provide an anonymous function instead (https://kotlinlang.org/docs/lambdas.html#anonymous-functions). In anonymous functions a return works like you're used to, but but the whole code gets more verbose. Here's an example: https://pl.kotl.in/4NQ4lMasf
3) Destructuring is worthless without naming. I visited the KotlinConf2024 and in one talk they said there are going to fix this (Kotlin 2.3??), probably in this one https://www.youtube.com/watch?v=tAGJ5zJXJ7w&list=PLlFc5cFwUn...
4) Coroutines. If I'm writing a Spring app, I (generally) don't use those as well. The exception was an reactive Spring with Webflux app that I converted from Java to Kotlin where the native coroutines constructs were just nicer (and more secure thanks to structured programming) than using Mono/Flux (see https://www.baeldung.com/kotlin/spring-webflux-kotlin). But I use Ktor in several of my newer apps and there coroutines are the only option. I admit that I struggled for a long time with coroutines. I read a tutorial or official documentation here and there, got the gist of it, but things got fuzzy soon enough. But I want to recommend the 3rd chapter of the 2nd edition of "Kotlin in Action". This is the best description of coroutines I've ever read and I finally got the feeling that I understood the whole thing! https://www.manning.com/books/kotlin-in-action-second-editio...
In Raku the ternary was changed to ‘exp ?? True !! False’ to free up the single characters ‘?’ and ‘:’ for other purposes.
IME it’s not such a large shift for the developer (still easily recognizable as a ternary) while also having the benefit of slightly increasing the visibility of ternary expressions in the coding experience.
Edit: Thanks for the coroutine reading recommendation. I’ve been struggling a bit with them and have a few in use but would definitely like to grok them better.
I'm actually in team no-ternary operator in Kotlin, simply because there shouldn't be two ways of doing the same thing.
Maybe the problem is a linter issue:
for me the main point of the ternary operator to have a very concise expression, a one-liner. But maybe our linters warn when a) we use if-else without braces and b) we put everything on the same line!??
Btw there is already another way to write the ternary operator in Kotlin (assuming the positive-case value of expression X is non-nullable):
"C ? X : Y" -> "X.takeIf { C } ?: Y" https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/take-if... Though I admit, I've never used this version either.