Safety
How many classes of bugs does the language prevent for you?
Five categories — memory safety, null derefs, data races, integer overflow, and type coercion — each scored by when the protection kicks in: compile-time (best), runtime, or not at all. Weighted by real-world CVE impact. How we score →
Results
| Language | Score | Memory | Null | Race | Overflow | Coercion |
|---|---|---|---|---|---|---|
| Elixir | 5 | compile | compile | compile | compile | compile |
| Milo | 5 | compile | compile | compile | compile | compile |
| Haskell | 4.8 | compile | compile | compile | runtime | compile |
| Rust | 4.8 | compile | compile | compile | runtime | compile |
| Erlang | 4.7 | compile | runtime | compile | compile | compile |
| Clojure | 4.3 | compile | runtime | runtime | compile | runtime |
| Swift | 4.3 | compile | compile | runtime | runtime | compile |
| Kotlin | 3.9 | compile | compile | runtime | none | compile |
| Python | 3.8 | compile | runtime | none | compile | runtime |
| Ruby | 3.8 | compile | runtime | none | compile | runtime |
| C# | 3.7 | compile | compile | runtime | runtime | runtime |
| Go | 3.5 | compile | runtime | runtime | none | compile |
| TypeScript | 3.3 | compile | compile | none | none | compile |
| Zig | 3.3 | runtime | compile | none | runtime | compile |
| Java | 3.1 | compile | runtime | runtime | none | runtime |
| JavaScript | 2.3 | compile | none | none | none | none |
| C++ | 1.1 | runtime | runtime | none | none | none |
| Objective-C | 0.8 | runtime | none | none | none | none |
| C | 0 | none | none | none | none | none |
What the categories measure
| Category | Weight | What it prevents |
|---|---|---|
| Memory | 45% | Use-after-free, double-free, buffer overflow, uninitialized reads |
| Null | 20% | Null/nil pointer dereference |
| Data Races | 15% | Two threads mutating shared state concurrently |
| Overflow | 12% | Integer overflow silently wrapping |
| Coercion | 8% | Implicit type coercions ("5" + 3 → "53") |
Weights reflect real-world impact: ~70% of high-severity CVEs are memory safety bugs (Microsoft, Google Chrome). Integer overflow dropped out of the CWE Top 25 in 2025.
Notable tradeoffs
Rust (4.8) — near-perfect but not 5.0. Integer overflow panics in debug mode, wraps in release. The borrow checker prevents memory, null, and race bugs at compile time.
Go (3.1) — GC handles memory, but null panics at runtime (no Option type), race detection is opt-in (-race flag), and no overflow protection.
TypeScript (3.3) — GC handles memory. Null and coercion protection require strict mode (opt-in). No overflow or race protection.
Python (3.8) — GC + arbitrary-precision integers (no overflow possible). But no race protection and coercion is runtime-only (True + 1 → 2).
C (0) — no protection in any category. Every bug class is the programmer's responsibility.