Mehdi Akiki

Writing archive

Everything published under Writing, newest first. Each entry is labelled as part of an investigation, an article or reference. Short engineering notes have their own archive.

  • Published on

    Investigation · Part 10 of 10 · Types under the hood

    Types as Proofs: What the Checker Knows That the Binary Forgets

    Wrapping an f64 in a Meters type makes adding meters to seconds a compile error, and the optimized build merged the wrapped addition with the plain one into a single function. Then I fed the same function disguised bits and it computed a wrong answer without complaining. This is the last article of the series.
  • Published on

    Investigation · Part 9 of 10 · Types under the hood

    Runtime Type Tags: What Dynamic Languages Keep That Static Ones Throw Away

    A Python integer with the value 1 takes 28 bytes, and a million of them cost 36 MB where Rust would use 4. I expected mixed arrays to be slow in V8 and they were not. The cost that did show up was object shape, and it arrives as a cliff at the fifth shape.
  • Published on

    Investigation · Part 8 of 10 · Types under the hood

    The Processor Has No Types: What add Does to Bits It Does Not Understand

    I compiled the same operations for i32 and u32. Addition produced one shared function, comparison used the same compare instruction with a different flag, and division and shifting used different instructions. Where the sign lives in the machine code is not where most people expect.
  • Published on

    Investigation · Part 7 of 10 · Types under the hood

    Two Ways to Make a Type Disappear: Erasure and Monomorphization

    One generic function used with three types produced three copies in the Rust binary and one function in the JavaScript output. I counted the symbols, found the vtable jump, and argue that monomorphization is a trade most code makes without measuring it.
  • Published on

    Investigation · Part 6 of 10 · Types under the hood

    Where a Type Becomes a Layout: Fields, Padding, and Reordering

    The same three fields take 8 bytes in Rust and 12 in C, because rustc reorders them and C does not. I measured both, plus repr(C) and repr(packed), and this is the one place where a type leaves a physical trace the processor can touch.