Visualizing Rust's Vtables: How dyn Trait Works In Memory
16 points by ettolrach
16 points by ettolrach
Coming from C++, one of the most interesting features of Rust is the way dyn works, as explained here, by storing the vtable pointer together with the object pointer instead of inside the object. This is a better version of the “you don’t pay what you don’t use” principle.
Both ways are useful depending on what you're doing. It's a tradeoff, neither is inherently better, though I do suspect that the Rust way is probably a better default for Rust.
As an example of this, anyhow, a very popular error handling package, uses unsafe to implement the C++ way of doing dynamic dispatch here, because one pointer vs two when returning errors everywhere is a significant savings.
It’s also different from Haskell which passes the vtbl as a separate argument (as described in Wadler & Blott which I mentioned recently). Unlike Rust, Haskell requires the arguments and result of numeric operators to have exactly the same types, and the common operators are bundled into fewer traits/typeclasses. I don’t remember seeing an analysis of the design differences between Haskell’s typeclasses and Rust’s traits and how they relate to the design of the standard libraries, but I expect it would be illuminating.
One philosophical difference is that in Haskell typeclasses are meant to represent concepts associated with laws. For example the Num class defines both addition and multiplication but it also assumes associativity, distributivity etc. Instead in Rust traits are not often used in this sense (PartialEq being an exception). They really just say that their methods exist. So it does not buy anything to bundle addition and multiplication into the same trait.