An email I sent a friend about my Rust odyssey. I wonder what you think of it, @perry .
In every GCed language I’ve ever known of, the default is “boxed”. Got a type of struct? The fields are pointers (or primitive ints). Got a type of array of that struct? the array entries are pointers to blocks, one for each struct. Etc. Boxes everywhere. And it is well-known that boxing isn’t free. OCaml floats are the full 64 bits – no room for a bit saying whether the datum is a pointer or a primitive value. So by default, a float is boxed. But OCaml has a hack where they can have special “float arrays” that are unboxed, which saves enormous memory and instruction-count. Critical for making any sort of numeric code not suck. Just an example. There are a ton. Java has had this problem too – I remember me and P.A. were trying to figure out how to do unboxed structs in Java: it was a PITA and it sucked.
There was an attempt to build an ML compiler at CMU, called “TIL” (IIRC, “typed intermediate language”). The idea was what they called "nonparametric polymorphism. So a function that takes array could be compiled into multiple versions, one for array<struct{int, int}>, another for array, another for array (for all the rest). The idea being that along with the type-parameter, flowed “boxing information”.
It worked, from what I remember, but never caught on.
Time passes, and Rust comes along. And in Rust, everything is unboxed except for a few types: “Vec”, “Box”, “Rc”, “String”, a few others. Everything else is unboxed. And there’s even a “trait” that you can put on a type, that demands that its size be known at compile-time (“Sized”) to facilitate this. So what’s the point of this? Well, Rust tries to put everything on the stack. Everything. And when you have a Box, that Box … tries to have everything in the tree beneath it, all unboxed in the block it points at. So Rust privileges and biases toward unboxing everywhere. Boxing is what costs you thought and care and preparation.
This is a fundamentally different way of organizing code (and probably, your compiler too). And I wonder if it accounts for much of what makes Rust so fast.