3 ms·
I’m not convinced that the problem is actually a problem. Suppose someone writes a type PairOfNumbers with a couple fields. The author did not define a seriali
by amluto 7mo ago
I’m not convinced that the problem is actually a problem. Suppose someone writes a type PairOfNumbers with a couple fields. The author did not define a serialization. You use it in another type and want it to serialize it as:
{ "a": 1, "b": 2 }
I use it and want to serialize it as:
[ 1, 2 ]
What we’re doing is fine. You should get your serialization and I should get mine. But if either of us declares, process-wide, that one of us has determined the One True Serialization of PairOfInts, I think we are wrong.
Sure, maybe current Rust and current serde make it awkward to declare non-global serializers, but that doesn’t mean that coherence is a mistake.
- lmm 7mo ago> What we’re doing is fine. You should get your serialization and I should get mine. But if either of us declares, process-wide, that one of us has determined the One True Serialization of PairOfInts, I think we are wrong. Well, fine, but then you need to actually implement a module system or something. Currently trait impls are program-wide, and if you say that you're not allowed to make global impls of a trait then that's the same as saying you're not allowed to implement traits at all.
- amluto 7mo agoRust’s orphan rule has the property that there is no spooky action at all distance in terms of program semantics. If I write a library, my library behaves the same way regardless of whether the main program imports a different library. In any case, the OP’s proposed “incoherent” scheme actually is a module system of sorts for conflicting trait impls, and it seems about right for something like serialization.
- mattstir 7mo agoPerhaps that's fine in the particular case of serialization, but that line of thinking breaks down at more fundamental operations like `PartialEq` or `Hash`. Having a different definition for equality fundamentally breaks the program if the two versions ever mix. On the flip-side, it's important that the author is allowed to declare the "correct" way to do something, e.g. in a smart pointer crate where the safety of the program relies on a correct implementation. If traits weren't program-wide, you're just kicking the bucket down the road from the library author having to do define every trait impl to every user defining every trait impl, which is even worse imo