5 ms·
Well it means that the second you need a setter you can't use records so all the boilerplate remains.
by throwpupper 5y ago
Well it means that the second you need a setter you can't use records so all the boilerplate remains.
- zaphar 5y agoWhy would you need a setter for a data class? They add no value there.
- deleted 5y ago[deleted]
- valenterry 5y agoYou are supposed to create a new copy with some of the fields changed. Just like you do it with the java.time.* classes and others.
- bcrosby95 5y agoYet the only mechanism for this is error prone or relying on mountains of boilerplate.
- vbezhenar 5y agoInstead of changing few bytes, now I have to copy hundreds of bytes around and add more stuff for GC to collect. Well, they have to obey Wirth's law, I guess.
- JackFr 5y agoYou have to copy less than you think. Because the data is immutable, you can share everything but the changed fields.
- The_rationalist 5y agoThen you've invented mutability without references/identity. Except those are desired properties for data classes, unlike for value classes which have such semantic difference. Btw Kotlin allow to make immutable Java records too so clear winner.
- pkulak 5y agoNot sure what you're getting at. Immutable means exactly that. If you hand out an object, then do a copy change, that change isn't reflected in the object you gave to another method/thread/fiber/etc. Immutability doesn't mean application state never changes; it means that a single reference will always point to memory that hasn't changed.
- kaba0 5y agoParent means basically the difference between identity and primitive/value classes. In Haskell, you’ve only got the latter (maybe you can manage something with lower level controls exposed), that is in a non-haskell syntax new Point(3,2) == new Point(3,2), even though in memory the two object is different. “Problem” is with records, that they are only shallowly immutable. record Rect(List<Point> corners) will readily hand out a “pointer” to a mutable list. It can be solved of course by storing only immutable objects. What parent may have failed to get from grandparent comment is that the latter likely meant it under the hood, transparently to the user. That is, new Point(3,2) != new Point(3,2) but the JVM can make the object reference the same data, because the field itself is final. Thus a copy can be optimized at the JVM level, while still having identity.
- marcinzm 5y agoI mean, you do realize that you're writing Java code right? If you want ultimate low level optimization and control then you're already about ten miles too far downstream to make that turn. Also, I'm guessing the copy overhead is more than offset by the JVM being able to do better optimizations around these data structures.
- iainmerrick 5y agoStructs with mutable fields is hardly “ultimate low level optimization”, it’s something a lot of programmers still use as a matter of course. (I say this as a fan of immutable data!) Ultimate low-level optimization in Java would be more like packing your structure into arrays of integers - which is something people actually do in Java. Just because you’re using Java doesn’t mean you don’t want your code to run as fast as possible.
- kaba0 5y agoOr you know, the JIT will trivially optimize away the old class if it is reassigned to the same variable, as you would use it inside a loop. How do you think the litany of FP languages work? Like Haskell, Scala, Clojure?
- slver 5y agoIt can be done in theory, but the JVM does nothing of the sort right now.
- kaba0 5y agoFalse. The JVM already does quite a good job with escape analysis, and record types just add extra semantic information to potentially further improve the situation.
- the_gipsy 5y agoYou write java and worry about bytes copied?
- vbezhenar 5y agoYes, I do. Java could be quite fast if you won't slow it down on purpose.
- davewritescode 5y agoThis has been argued ad nauseam around the time Scala started gaining traction because scala's collections are grouped into immutable and mutable. The consensus at the time is that the GC overhead is well worth the ability to parallelize computation.
- krzyk 5y agoGC is there for a reason, unless you do HFT, use it to your advantage.
- kelnos 5y agoI don't know if the JVM developers have actually implemented this, but since records are immutable, there's no reason why a copy couldn't share memory between the instances. The major downside is that could ruin cache locality and make passing the instance across a FFI boundary require a copy. Another optimization would be that the JIT (or even perhaps javac) could notice cases where you make a copy (with one field changed) of a record and then never use the original reference again. If the JIT (or javac) can prove that no other bit of code holds a reference to the original record, it can reuse and mutate the original one instead of making a copy. I don't know if this optimization is or will be implemented, of course. Either way, I expect the overhead you mention ends up being worth the benefits of immutable data. (That's been my experience using Scala, anyway.)