The axis you were already drawing

Posted 2026-08-28 05:00:00 ‐ 1 min read

Every language comparison draws one line. That line is hiding two more.

Draft scaffold — the diagram below is the finished piece; the prose around it is still to be written.

controlsafetycost to wieldPython: control 0.03, safety 0.50, cost 0.10. Cheapest to start; the type system asks nothing of you and catches nothing for you.PythonJS: control 0.10, safety 0.45, cost 0.15. Safe from crashes, unsafe from nonsense: no data races because there are no threads to race.JSGo: control 0.45, safety 0.60, cost 0.20. Memory safe and famously cheap to learn, but data races are possible and easy to write.GoC#: control 0.35, safety 0.70, cost 0.30. More control than its reputation (structs, Span<T>, stackalloc); nullable refs closed a real hole.C#C: control 0.95, safety 0.10, cost 0.35. Total control, no guarantees, and UB that invalidates reasoning about the whole program.CZig: control 0.95, safety 0.40, cost 0.45. Runtime safety checks and explicit allocators, but no borrow checker and no data-race protection.ZigC++: control 0.95, safety 0.25, cost 0.75. RAII and smart pointers are real gains, but nothing is enforced; the surface area is enormous.C++Rust: control 0.90, safety 0.95, cost 0.80. Alone in rejecting data races at compile time without a GC. Not 1.0: unsafe exists, and logic bugs remain.Rustmanual memorygarbage collectedRustthe trade-off everyone assumesThree axesand here is what leaving the line costs
Scores and reasoning
Scores behind the diagram. These are judgements against a written rubric, not measurements.
LanguageControlSafetyCost to wieldMemoryWhy
C0.950.100.35manualTotal control, no guarantees, and UB that invalidates reasoning about the whole program.
C++0.950.250.75manualRAII and smart pointers are real gains, but nothing is enforced; the surface area is enormous.
Zig0.950.400.45manualRuntime safety checks and explicit allocators, but no borrow checker and no data-race protection.
Rust0.900.950.80manualAlone in rejecting data races at compile time without a GC. Not 1.0: unsafe exists, and logic bugs remain.
Go0.450.600.20garbage collectedMemory safe and famously cheap to learn, but data races are possible and easy to write.
C#0.350.700.30garbage collectedMore control than its reputation (structs, Span, stackalloc); nullable refs closed a real hole.
JS0.100.450.15garbage collectedSafe from crashes, unsafe from nonsense: no data races because there are no threads to race.
Python0.030.500.10garbage collectedCheapest to start; the type system asks nothing of you and catches nothing for you.

Notes toward the article

  • The single "low level ↔ high level" axis everyone draws is really control. Nothing about the ordering changes when you rename it, which is why stage 0 and stage 1 share an x coordinate: it is the same axis, honestly relabelled.
  • safety is the thing that axis was hiding. Splitting it out is what makes C and C++ stop being the same point.
  • The dashed line is the folk model: control and safety trade off, pick one. Rust is visibly off it. So, for that matter, is Go — less dramatically.
  • cost is where Rust does worst, and it is on the chart on purpose. A chart where the subject wins on every axis reads as advocacy, not measurement.
  • The finding worth writing up: cost tracks distance from the trade-off line — except for C++, which pays close to Rust's price without buying Rust's escape from the line.