A long winded article that really never justifies its headline. Kotlin will soon be generating records in its back end, thereby gaining all the advantages that it's allegedly not getting today.
Java's records, Lombok's data, and Kotlin's data classes
281–290 of 294 posts
Re: Java's records, Lombok's data, and Kotlin's data classes
#282I think the article is misleading in the list of advantages over Kotlin's Data Classes. 1. Destructuring - available in Kotlin 2. Copy with change - available in Kotlin 3. Serialization - not sure why Kotlin data class would not be serializable 4. Boilerplate - Kotlin takes care of equals and hashCode Huge disadvantage that matters to me is that record fields cannot be mutated. It makes the records much less useful.
Re: Java's records, Lombok's data, and Kotlin's data classes
#283Earlier quoted context omitted.
Scala has the full suite of Java collections without any conversion or overhead whatsoever. But it also has Scala collections. With scala collections you get the full power of the Scala type system, as well as a much richer and full featured collections api. So most scala programmers won't bother with java collections unless they have specific java interop requirements. The Scala adapters are merely ways of convertin…
I think it's a fair complaint that in Scala it is a pain in the ass to deal with Java collections. You have to litter your whole code with `.asScala` and `.asJava`, the java collections don't work with for comprehensions, etc.
The problem is that those java collections suck in comparison to the Scala collections. So Scala programmers prefer to use Scala collections. Scala programmers would never willfully use java collections if they don't have to, and if they absolutely have to, they have minimal overhead conversions back and forth. The minimal conversion overhead is the price they're willing to pay to use better collections while maintaining java interoperability.
Re: Java's records, Lombok's data, and Kotlin's data classes
#284Earlier quoted context omitted.
> I'll start with one (key)word: `implicit` I don't think implicit counts as "too many features" or as something complex. Basically all it does is finding a canonical value in scope for a hole of certain type.
I only worked in Scala briefly so maybe it's coming from Java habits, but implicits were huge pain. When first reading through code you don't really know if that function call you eyed over really has the params you think it does. It makes it WAY harder to track what's derived from what. Either way, the local Scala guru there said the Scala community was starting to get over implicits.
Yeah, but don't you feel the same pain when using Spring's autowiring? Or python's (or C++ template) default arguments? Or dynamic method dispatching in any OO language, where you don't know what method you actually call? Or late bindings?
I don't see how implicits' implicitness is significantly worse than any other kind of implicitness common in other language.
Re: Java's records, Lombok's data, and Kotlin's data classes
#285Earlier quoted context omitted.
I think it's a fair complaint that in Scala it is a pain in the ass to deal with Java collections. You have to litter your whole code with `.asScala` and `.asJava`, the java collections don't work with for comprehensions, etc.
No, it's not hard. In Scala, you are completely free to use those java collections and you can do it exactly how kotlin programmers do it. You want a java list, without any need to convert back and forth between Scala and Java? Import `java.util.List`. All of the same methods and iterators and expressions and constructs are still there. You get all of the lack of capabilities and grace that the java collections provi…
Kotlin:
listOf(1,2,3,4)
.map{i -> i + 1}
.filter { it % 2 == 0 }
.flatMap { listOf(it, it * 2, it * 3) }
Kotlin even has a similar take to Scala's views, which they call sequences: listOf(1,2,3,4)
.asSequence()
.map{i -> i + 1}
.filter { it % 2 == 0 }
.flatMap { listOf(it, it * 2, it * 3) }
.toList()
Is this really so "lacking in capability and grace" compared to Scala? The only think missing is persistent immutable collections, which are implemented in kotlinx.Re: Java's records, Lombok's data, and Kotlin's data classes
#286Kotlin data classes can use Java records as their implementation if running on JVM, so it’s not like you have to choose one or the other. https://kotlinlang.org/docs/jvm-records.html#declare-records...
That misses the point. The strength of records is that the language can build features that are only possible because of records' restrictions. It's not that the bytecode says "I'm a record" - which is all you get if Kotlin compiles a data class to one. @JvmRecord gives you all the limitations with none of the benefits. The annotation only exists for compatibility reasons.
The reality is that Kotlin can build the very same benefits you're talking about as well, in future versions. All the compiler has to do is to restrict these benefits to data classes which only have 'val' members, do not have hidden state and do not use inheritance. In fact, Kotlin is ALREADY enforcing these constraints on a any data class that you annotate with @JvmRecord.
Now, if we're already talking about imaginary future benefits here, Kotlin is also planning to have (immutable by design) value classes when Project Valhalla is ready (you can already have value classes with a single field in Kotlin 1.5).
[1] To be fully honest, Java records themselves are themselves an imaginary feature for the vast majority of Java users until Java 17 comes out, since very few projects would use a non-LTS version. And even then, you can expect years until libraries can start to use them. Kotlin and Lombok data classes can be used right now.
Re: Java's records, Lombok's data, and Kotlin's data classes
#287A long winded article that really never justifies its headline. Kotlin will soon be generating records in its back end, thereby gaining all the advantages that it's allegedly not getting today.
That misses the point. The strength of records is that the language can build features that are only possible because of records' restrictions. It's not that the bytecode says "I'm a record" - which is all you get if Kotlin compiles a data class to one. @JvmRecord gives you all the limitations with none of the benefits. The annotation only exists for compatibility reasons.
The only benefits I've seen in your article are not available right now, and can (and sometimes are) matched by Kotlin and even Lombok.
* Destructuring pattern matching syntax (JEP 405)
Proper pattern matching is obviously one of Kotlin's weak spots, but nothing prevents it from developing this in the future. Just like Java has JEP 405, Kotlin has KT-186[1], although Java might (uncharacteristically) beat Kotlin to this one.
* with blocks
This solution is far away and relies on introducing new syntax to the language. Meanwhile both Kotlin and Lombok already have solutions that give you the same benefits without introducing new syntax.
Lombok has both @With and @ToBuilder, while Kotlin has the copy() method.
* Serialization
As far as I can see, Kotlin Serialization already supports algebraic data types - including Sum Types, not just Product Types!
* Boilerplate reduction
I don't think you were trying to imply otherwise, but just to be clear about it, this is the benefit that both Kotlin and Lombok data classes had from day one.
Re: Java's records, Lombok's data, and Kotlin's data classes
#288Earlier quoted context omitted.
Kotlin doesn't have immutable collection types in the standard library (it lets you use a read-only interface but the collection is really still mutable and will be seen as such by any Java code), so if you want actually immutable collections you have to use non-standard collections, and since Kotlin doesn't have typeclasses or implicit conversions it's difficult to interoperate between any non-standard collection li…
Ah, fair. I've never actually seen that become a problem, but I can see how it would be if I were doing more extensive Java interop.
Re: Java's records, Lombok's data, and Kotlin's data classes
#289Earlier quoted context omitted.
I only worked in Scala briefly so maybe it's coming from Java habits, but implicits were huge pain. When first reading through code you don't really know if that function call you eyed over really has the params you think it does. It makes it WAY harder to track what's derived from what. Either way, the local Scala guru there said the Scala community was starting to get over implicits.
> When first reading through code you don't really know if that function call you eyed over really has the params you think it does. Yeah, but don't you feel the same pain when using Spring's autowiring? Or python's (or C++ template) default arguments? Or dynamic method dispatching in any OO language, where you don't know what method you actually call? Or late bindings? I don't see how implicits' implicitness is sign…
Default params are generally fine since they're hidden on the implementation side but explicit if they vary at the caller site.
And even dynamic dispatch I try to use carefully and sparingly. I just like really explicit programs.
Re: Java's records, Lombok's data, and Kotlin's data classes
#290Earlier quoted context omitted.
No, it's not hard. In Scala, you are completely free to use those java collections and you can do it exactly how kotlin programmers do it. You want a java list, without any need to convert back and forth between Scala and Java? Import `java.util.List`. All of the same methods and iterators and expressions and constructs are still there. You get all of the lack of capabilities and grace that the java collections provi…
Except Kotlin enjoys the compatibility with Java, plus it outfits those java collections with extension methods and some compiler tricks to achieve all the same functionality as the Scala collections (in fact, I would say even more self-consistent and useably than in Scala). Just as in Scala, in Kotlin you can use functional transforations that Scala users are so accustomed to: Kotlin: listOf(1,2,3,4) .map{i -> i + 1…
You said:
> You have to litter your whole code with `.asScala` and `.asJava`, the java collections don't work with for comprehensions, etc.
So how does kotlinx achieve zero-cost compatibility with Java collections without having something like `.asKotlin` and `.asJava`? Because otherwise there is no difference between Scala and Kotlin in this regards.