3 ms·
I'm sure there are good reasons for why record classes are the way they are. But the reasons you cite strike me as a bit esotheric / low value. Serialization w
by jillesvangurp 4y ago
I'm sure there are good reasons for why record classes are the way they are. But the reasons you cite strike me as a bit esotheric / low value.
Serialization works fine with kotlinx.serialization. Java's built in serialization is a bit of a relic of the past that doesn't really have that many use cases left. I'll write that off as a "I couldn't care less". I've actually used java serialization but not this century. There probably is still some legacy stuff around that depends on it but nothing a typical Kotlin user would care about.
As for collections. Not sure what you mean here. The Java collections take just about any object. Including data class objects. You need working hashcode and equals implementations. Which are provided by data classes. There are some limitations with deep comparisons particularly with array types. The Kotlin compiler will warn you about those. Am I missing something else here?
Constructing/destructing seems to work fine for me. Nice feature. Copy constructors in particular are neat. Am I missing out on something here?
You make it sound that this is kind of a big deal or a big compromise but I just don't see it.
- pron 4y ago> I've actually used java serialization but not this century. I'm not talking about Java's built-in serialization but any kind of serialization. An object with hidden state cannot be safely deserialised regardless of mechanism. Hidden state, by definition, means that its consistency (which may translate to security) is not validated by mechanisms that are known to the deserialisation mechanism. Safe serialisation requires that there be no hidden state, i.e. that all of the objects state is validated by public mechanisms. > You need working hashcode and equals implementations. Which are provided by data classes. No, that's not enough. Some collections (such as hash maps and has sets) additionally require that the hashCode does not change over the object's lifetime, or at least over the time the object is in the collection. > Constructing/destructing seems to work fine for me. Reconstruction can only work when all of the object's state is deconstructed. That's not the case for data classes. The result will be equal in the `equals` sense, but the resulting object will not be substitutable for the original. Equal records are substitutable (unless you depend on object identity, but object identity is the focus of another project -- Valhalla) > but I just don't see it. The powerful properties of algebraic data types have been studied for half a century now, and there's a lot of literature you can find on the subject. That's not to say that data classes aren't helpful, but they only address the problem of syntax ceremony. Records, by focusing on semantics, not only on syntax, additionally address other important problems.
- wiseowise 4y ago> No, that's not enough. Some collections (such as hash maps and has sets) additionally require that the hashCode does not change over the object's lifetime, or at least over the time the object is in the collection. If everything declared val in Kotlin, wouldn't that be enough?
- pron 4y agoSure, just as any immutable object is fine in this regard. But the point is not the fact that we can write some classes that are well-behaved in certain respects, but that we can reify a concept as construct known to provide those guarantees. That's exactly what enums and records do, but data classes don't. You could always code regular classes with behaviour similar to that of enums or records, but the point of enums and records is that all enums and all records are known to have their respective kind of behaviour.
- hota_mazi 4y agoYour characterization of "hidden state" doesn't make a lot of sense. Either a state is part of the object's identity, and it's serialized, or it's not, and it's not. This observation has nothing to do with data classes, records, Java, or Kotlin. > The result will be equal in the `equals` sense, but the resulting object will not be substitutable for the original. This doesn't make sense either. You are describing someone who implemented flawed serialization. It's a programmer error, not a language or semantic one. I see very little difference of practical importance between Java's records and Kotlin's value classe, and as much as I value your technical writings, I am concerned that your employer is tainting your objectivity when trying to compare Java and Kotlin. You can do better.
- pron 4y agoWhat's serialised is not identity but state. If any part of the state is hidden, i.e. serialization needs to set it not via the object's public API, then serialization can break the object's invariants. This is what serialization vulnerabilities are. You certainly can write classes with safe serialization, but serialization vulnerabilities happen because sometimes people don't. Sure, it's an error, but it is one of the errors that enums and records were created to avoid. But it is true that we can live without records and enums, and, indeed, we did, so I wouldn't say they're critical features. Still, I think it's important that people know that records and enums -- unlike data classes, which are syntax sugar -- were added for the guarantees they make regarding certain behaviours, including interaction with collections and with serialization (of any kind).