3 ms·
> 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
by 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).
- hota_mazi 4y ago> What's serialised is not identity but state. These are not mutually exclusive and they describe actually two very different concepts. If your objects will end up in a hashing container, you absolutely need to serialize what makes their identity. If not, you can serialize whatever you need from the object. It can be more fields than its identity, or fewer. I'm not sure what your following point about serialization vulnerability (however correct) has to do with the current discussion.
- jillesvangurp 4y agoThis sounds like a whole lot of "just don't do that". Making properties mutable in Kotlin is a choice. I typically don't. I also don't keep a lot of hidden state in my data classes. Why would I? And when I do, I mark those properties as transient/ignored for the serialization framework I use. Or I make them extension properties that are calculated from the other properties. None of the things you list are actually an issue unless you choose to do silly things like having hidden state and vars instead of vals. You call that a problem, I call it flexibility. As for hash codes not changing. That is indeed nice if you have a hash map but I've never come across that one as being a hard requirement. Just that objects that are equal must have the same hash code. So, this too is a non issue unless you do silly things that cause that to not be true. Like having mutable, hidden state that is then taken into account in your hash code function but not in your equals function. Also worth pointing out that Java has had fully open and mutable classes by default with lots of hidden state and the collection classes have been there since java 1.1 (or 1.2) long before generics were even a thing. So, unless something changed there, people have been using them wrong for the last 20+ years.
- pron 4y ago> You call that a problem, I call it flexibility. You misunderstand my point, I think. Java already offers you all that flexibility with regular classes, and data classes are just syntax sugar for creating regular classes. It's not that data classes have a "problem" so much as that they're just yet another syntactic construct, while records and enums are something else. Of course, a hosted language (let alone one that targets multiple platforms) is quite limited in the kinds of constructs it can offer, as it has no influence over the runtime and the ecosystem, but it's still important to understand that data classes and records are features of a different nature. > So, unless something changed there, people have been using them wrong for the last 20+ years. Regular classes can, indeed, mimic the behaviour of enums and records, but the reason enums and records were added was that these construct provide guarantees of correct use, guarantees that the language and the runtime now rely on. True, we can and did live without them, and they're not absolutely critical. But they're still powerful, and their power is not a result of their succinct syntax but of their behaviour.