DEV Community

Dimension AI Technologies
Dimension AI Technologies

Posted on

13 Languages Are Challenging C. Most Fail. Only Five Stack Up.

"Which language is better than C?"

That's an interesting question, but it's not even worth answering.

The correct question is:

"Which languages can occupy C's position in the software stack?"

The reason: C is far more than just a syntax. It is the binary and organisational substrate of modern computing. Every kernel, every runtime, every Python module, every shared library — they all pass through C at some point.

So "replacing C" means replacing that role, not just writing nicer code.

This essay examines C against thirteen "challenger" languages that are known — by their communities or by observers — as C-adjacent, low-level or C successor candidates.

We applied a systematic methodology using five filters to identify which ones are genuinely competing for C's throne — and which ones are solving different problems entirely.


What C actually is

C has been reigning champ of low-level procedural programming for over 50 years. You can think of it as having an alias-centric memory model — a metaphor, not a formal model, but a useful one.

Its defining axiom is:

Memory is bytes; pointers alias; mutation is unrestricted.

Everything else follows from that.

The compiler cannot assume anything about pointer targets. Mutation is always dangerous; undefined behaviour is unavoidable; and concurrency is hostile by default.

C's power comes from unrestricted aliasing. C's fragility also comes from unrestricted aliasing.

C is nonetheless:

  • The ABI lingua franca
  • The OS interface
  • The library boundary
  • The toolchain anchor

C is the dangerous uncle everyone still invites to dinner — because he owns the house.


The "C-family" illusion

What we call the "C family" is really:

A shared grammar sitting on top of incompatible execution models.

C-family syntax means braces, semicolons, infix operators, if (…), for (…), while (…), and block-scoped variables. These define a parser-level classification but not a semantic one.

Java, Rust, Zig, Go and C# look related because their keywords, braces and semicolons are so similar. But they are not related at the level that matters: aliasing, lifetime and memory ownership.

The economic reason is simple: C syntax is the QWERTY keyboard of programming. Changing it raises training cost without improving machine-level behaviour.

C syntax won; C semantics didn't. Every major descendant kept the braces but rewrote the rules underneath.


The four real semantic families

Once you strip syntax away, all C-inspired languages fall into four execution models, defined by who controls memory and aliasing.

Model Who owns memory? Who enforces safety? Examples
Unmanaged Programmer Nobody C, C++, Zig, Odin, Hare, C3, Carbon, Jai
Hybrid Programmer + runtime Partial D, Nim, V, Swift
Managed Runtime GC Go
Verified Compiler Type system Rust

(Languages like Java, C#, and JavaScript also fall into the Managed category, but they don't claim to be C replacements, so we exclude them from this analysis.)

Important caveat: These buckets are coarse. They describe the default execution model, not every possible subset mode. D in -betterC mode behaves differently from idiomatic D; Swift in Embedded mode behaves differently from standard Swift. The taxonomy captures where each language's gravity pulls you, not where heroic effort can push you.


The five filters a real C-successor must pass

A language must be able to:

Filter Why it matters
Freestanding compilation Kernels, firmware, runtimes
Deterministic layout Structs and ABI are contracts
Stable C interop The world is already written
No mandatory runtime You must own the process
Toolchain-level visibility Debuggers, profilers, sanitizers

Most languages die here.

Critical distinction: A language passes these filters if its default compilation mode meets them, or if a first-class, maintained mode exists that does. Languages requiring unofficial hacks, unmaintained forks, or heroic effort to achieve freestanding operation do not pass.


The candidate pool

Here are the fourteen languages we'll evaluate. Each is discussed in public discourse as C-adjacent, low-level, or a potential C successor. Listed with core philosophy, semantic family, and a characterisation.

Language Year Philosophy Semantic family Characterisation
C 1972 "Trust the programmer" Unmanaged The dangerous uncle who owns the house
C++ 1985 "Zero-cost abstractions" Unmanaged C's midlife crisis
Rust 2015 "Make invalid states unrepresentable" Verified Your compiler's disappointed parent
Zig 2016 "No hidden control flow, no hidden allocations" Unmanaged C's responsible older brother
Odin 2016 "The joy of programming, distilled" Unmanaged C for people who ship video games
Hare 2022 "Stability is a feature" Unmanaged C if Dennis Ritchie had a time machine
C3 2019 "Evolution, not revolution" Unmanaged C with a sensible haircut
D 2001 "C++ without the baggage" Hybrid The language that tried to please everyone
Nim 2008 "Write like Python, run like C" Hybrid Python wearing a C costume to a job interview
V 2019 "Simple, fast, done" Hybrid The language of bold promises
Swift 2014 "Safety without sacrifice" Hybrid Objective-C's attractive replacement
Go 2009 "Simplicity scales" Managed Java in a hoodie
Carbon 2022 "C++ migration path" Unmanaged Google's C++ apology letter
Jai ~2014 "Game programmers know best" Unmanaged The language equivalent of "coming soon"

C is the baseline. The other thirteen are the challengers.

Scope note: This analysis restricts itself to C-adjacent languages actively discussed as C successors in modern discourse. It excludes Ada/SPARK, Pascal variants, and other capable low-level languages that aren't typically framed as "C replacements" in contemporary conversation. That's a scope choice, not a quality judgement.


The defining axioms

Each language can be summarised by what it believes about memory. But first, six definitions:

  • Memory: A flat array of addressable bytes. In C's model, any byte can be read or written if you have its address.
  • Pointer: A value that holds a memory address. Pointers let you indirectly access and modify data elsewhere in memory.
  • Aliasing: When two or more pointers refer to the same memory location. If p and q both point to address 0x1000, writing through p changes what q sees. This is powerful and dangerous.
  • Mutation: Changing the value stored at a memory location. Unrestricted mutation means any code with a pointer can modify that memory at any time.
  • Lifetime: The span during which a piece of memory is valid to access — from allocation to deallocation. In C, the programmer tracks lifetimes manually; use-after-free bugs occur when code accesses memory whose lifetime has ended.
  • Ownership: The responsibility for a piece of memory's lifecycle — who allocates it, who may access it, and who deallocates it. In C, ownership is a convention. In Rust, ownership is enforced by the compiler: every value has exactly one owner, and memory is freed when the owner goes out of scope.

C's defining axiom combines the first four: memory is bytes, pointers can alias freely, and mutation is unrestricted. Lifetimes and ownership are the programmer's problem. Every C-inspired language must decide whether to keep, constrain, or replace that axiom.

Language Axiom
C "Memory is bytes; pointers alias; mutation is unrestricted"
C++ "Memory is bytes; pointers alias; mutation is unrestricted; also here are 47 ways to abstract over that"
Rust "Memory is owned; aliasing is controlled; mutation is permissioned"
Zig "Memory is bytes; pointers alias; but we will tell you when you mess up"
Odin "Memory is bytes; pointers alias; but the defaults should be sensible"
Hare "Memory is bytes; pointers alias; but the language should be finished"
C3 "Memory is bytes; pointers alias; but the syntax shouldn't fight you"
D "Memory is whatever you want it to be today"
Nim "Memory is managed unless you insist otherwise"
V "Memory is managed but we're working on making it optional"
Swift "Memory is reference-counted; aliasing is... complicated"
Go "Memory is the runtime's problem, not yours"
Carbon "Memory is bytes; pointers alias; but we're fixing C++'s mistakes"
Jai "Memory is bytes; pointers alias; and we'll ship when we ship"

The C-ness comparison

How close is each language to C's actual execution model?

Scoring rubric:

  • C-like syntax: Braces, semicolons, infix operators, familiar keywords
  • C-style pointers idiomatic: Pointer arithmetic, manual aliasing, and explicit address manipulation are normal usage patterns
  • Safety checks optional: Bounds checking, null checks, and similar guards can be disabled or are off by default
  • Manual control: Programmer controls allocation, layout, and teardown without runtime intervention

Five stars means "basically C". Overall = minimum of the four columns (a language is only as C-like as its weakest dimension).

Language Syntax Pointers Safety Control Overall
C ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
C++ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐☆ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐☆
Zig ⭐⭐⭐⭐☆ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐☆ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐☆
Odin ⭐⭐⭐⭐☆ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐☆ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐☆
Hare ⭐⭐⭐⭐☆ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐☆ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐☆
C3 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐☆ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐☆
Carbon ⭐⭐⭐⭐☆ ⭐⭐⭐⭐☆ ⭐⭐⭐⭐☆ ⭐⭐⭐⭐☆ ⭐⭐⭐⭐☆
Jai ⭐⭐⭐⭐☆ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐☆
D ⭐⭐⭐⭐☆ ⭐⭐⭐☆☆ ⭐⭐☆☆☆ ⭐⭐⭐☆☆ ⭐⭐☆☆☆
Nim ⭐⭐⭐☆☆ ⭐⭐☆☆☆ ⭐⭐☆☆☆ ⭐⭐☆☆☆ ⭐⭐☆☆☆
V ⭐⭐⭐⭐☆ ⭐⭐☆☆☆ ⭐⭐☆☆☆ ⭐⭐☆☆☆ ⭐⭐☆☆☆
Swift ⭐⭐⭐☆☆ ⭐⭐☆☆☆ ⭐☆☆☆☆ ⭐⭐⭐☆☆ ⭐☆☆☆☆
Rust ⭐⭐⭐⭐☆ ☆☆☆☆☆ ☆☆☆☆☆ ⭐⭐⭐⭐☆ ☆☆☆☆☆
Go ⭐⭐☆☆☆ ☆☆☆☆☆ ☆☆☆☆☆ ⭐☆☆☆☆ ☆☆☆☆☆

Key insight: Zig, Odin, Hare, C3, and Jai are C-family in physics. Rust is C-family only in grammar.

Note: C++ does not have a stable C ABI; and the C ABI cannot handle templates, overloads or name-mangling - so C++ cannot substitute for C.


How C-like languages diverged

Every descendant of C had to decide what to do about C's aliasing axiom. They took four different paths.

Path A — Keep C's physics

Languages: C++, Zig, Odin, Hare, C3, Carbon, Jai

They kept pointer aliasing, manual lifetimes, and undefined behaviour as a feature (or at least as an explicit tradeoff). They only changed ergonomics, not semantics.

These are C-family in physics.

(Some of these keep C's physics but still fail the five filters for non-technical reasons: maturity, release status, or scope. Carbon targets C++ migration; Jai isn't released. Semantic similarity doesn't guarantee practical usability as a C successor.)

Path B — Hide C's physics

Languages: Go (and outside our candidate pool: Java, C#, JavaScript)

They removed pointer arithmetic, explicit lifetimes, and alias control. They replaced them with tracing garbage collection, moving heaps, and runtime checks.

These are managed VMs with curly braces. They look like C but execute like Java.

Path C — Half-escape

Languages: D, Nim, V, Swift

They offer raw pointers when you ask, GC or ARC when you don't, plus slices and bounds checking. This creates two languages inside one compiler.

They are not C and not safe. They rely on discipline plus runtime support.

Path D — Replace the memory model

Languages: Rust

Rust throws away C's axiom — "Memory is bytes; pointers alias; mutation is unrestricted" — and replaces it with: "Memory is owned; aliasing is controlled; mutation is permissioned."

That is a new machine model, enforced at compile time.

Rust does not make C safer. It makes a different kind of machine that happens to use C syntax.


Applying the five filters

We now take all fourteen languages and run them through the five filters. C is the baseline — it passes by definition. The other thirteen are sorted into three tiers.

Tier 3: Clear failures

These languages have fundamental design conflicts with substrate programming, or cannot be evaluated.

Go — "Simplicity scales"

Characterisation: Java in a hoodie

Go fails the "no mandatory runtime" and "freestanding" filters. It has a mandatory garbage collector, mandatory runtime scheduler, and goroutine stack management that requires runtime support.

This means Go cannot occupy C's substrate role. It can, however, occupy a different and valuable role.

The distinction matters:

  • Freestanding substrate programming = you control the machine (kernels, drivers, firmware, runtimes). No runtime beneath you.
  • Systems infrastructure programming = you build infrastructure software (containers, networking, CLI tools). Runtime handles memory and scheduling.

Go is excellent at systems infrastructure. Docker, Kubernetes, and countless networking tools prove this. But Go is structurally incapable of freestanding substrate work.

Illustrative example: Imagine a hardware interrupt with a ~10μs deadline. A garbage collector that might pause for milliseconds cannot coexist with that constraint. This isn't a criticism of Go — it's a category distinction. Go solves different problems.

Go replaces C in infrastructure. It does not compete for C's substrate role.

Carbon — "C++ migration path"

Characterisation: Google's C++ apology letter

Carbon's publicly stated focus is C++ interoperability and migration. It is not positioned as a freestanding substrate language today.

Carbon is a C++ successor, not a C successor. Different problem.

Jai — "Game programmers know best"

Characterisation: The language equivalent of "coming soon"

Not publicly released. No stable toolchain. Cannot be evaluated against filters.

C++ — "Zero-cost abstractions"

Characterisation: C's midlife crisis

C++ passes the technical filters — it has freestanding mode, deterministic layout, and full toolchain support. But C++ is not trying to replace C; it's trying to extend C. It occupies a different niche: large-scale application development with object-oriented and generic programming.

C++ is C's companion, not its successor.


Tier 2: Conditional passes

These languages can pass the filters, but only when compiled in a restricted mode that disables significant features.

D (with -betterC) — "C++ without the baggage"

Characterisation: The language that tried to please everyone

BetterC mode removes the GC, runtime, classes, exceptions, dynamic arrays, associative arrays, nested functions with context, and most of the standard library (Phobos). What remains is closer to "C with templates" than idiomatic D.

D's tragedy is that it's genuinely well-designed, but arrived too early (before Rust proved the market) and tried to be too many things. In BetterC mode, C++ plus garbage collection becomes just C with better syntax.

Verdict: Passes filters, but the mode strips so much that it's debatable whether "D" is being used or a D-shaped subset.

Nim (with manual configuration) — "Write like Python, run like C"

Characterisation: Python wearing a C costume to a job interview

Nim can be pushed toward freestanding and embedded targets, but it becomes a "bring-your-own-runtime-stubs" exercise. Debugging largely happens at the generated-C level. The ABI is the underlying C compiler's, not Nim's.

Nim is better understood as a C producer than a C successor. It doesn't replace C; it generates it.

Verdict: Technically achievable. Philosophically awkward.

Swift (with Embedded Swift) — "Safety without sacrifice"

Characterisation: Objective-C's attractive replacement

Swift has an experimental Embedded Swift compilation mode that produces standalone object files with no runtime required. It disables reflection, existentials, and ABI stability. It primarily targets ARM and RISC-V embedded platforms.

This is genuinely interesting. But Embedded Swift is experimental, and Apple's priorities are phones, not kernels.

Verdict: Passes filters in experimental mode. Ecosystem and tooling are nascent. Worth monitoring.

V (with -gc none) — "Simple, fast, done"

Characterisation: The language of bold promises

V has a manual memory management mode and community members have built experimental kernel projects. But V's autofree — its main selling point — is experimental and not production-ready. The language is pre-1.0.

V promised a lot. The jury is still out on delivery.

Verdict: Technically passes. Maturity concerns.


Tier 1: Clear passes

These languages pass all five filters in their default or primary compilation mode. Their distinctive features remain available when targeting the substrate.

Rust — "Make invalid states unrepresentable"

Characterisation: Your compiler's disappointed parent

Axiom: "Memory is owned; aliasing is controlled; mutation is permissioned"

What it really is: A safe systems language wearing C syntax as a compatibility layer.

Rust's no_std mode is first-class. The borrow checker works without the standard library. In December 2025, kernel maintainers agreed Rust support is no longer "experimental".

In safe Rust, the compiler enforces aliasing and lifetime rules that eliminate use-after-free and data races. This guarantee applies to safe code; unsafe blocks and FFI boundaries are the programmer's responsibility.

Trade-off: Borrow checker complexity. Steep learning curve. Interop with C requires unsafe blocks.

Zig — "No hidden control flow, no hidden allocations"

Characterisation: C's responsible older brother

Axiom: "Memory is bytes; pointers alias; but we will tell you when you mess up"

What it really is: C with a compiler that cares.

Zig has no runtime by default. It can replace not just C code but the C toolchain — it works as a drop-in C compiler and cross-compilation system. Comptime works without an OS.

Zig doesn't stop you shooting yourself in the foot. It hands you the gun with the safety on and a note explaining which end is dangerous.

Trade-off: Language still pre-1.0. API stability not guaranteed.

Odin — "The joy of programming, distilled"

Characterisation: C for people who ship video games

Axiom: "Memory is bytes; pointers alias; but the defaults should be sensible"

What it really is: Modernised C for large codebases.

Odin's freestanding target is first-class. The context system — Odin's mechanism for threading allocators and loggers through call stacks — works freestanding. Memory management is explicit.

Odin is what happens when someone who actually ships software designs a language, rather than someone who writes papers about shipping software.

Trade-off: Smaller ecosystem. Less tooling than Rust or Zig.

Hare — "Stability is a feature"

Characterisation: C if Dennis Ritchie had a time machine

Axiom: "Memory is bytes; pointers alias; but the language should be finished"

What it really is: What C might have been with hindsight.

Hare does not link to libc by default. It is designed explicitly for kernels, compilers, and system tools. The language specification will freeze at 1.0.

Hare's radical proposition: what if a programming language stopped changing?

Trade-off: Very early ecosystem. The project explicitly states support for Linux and FreeBSD only, on x86_64, aarch64, and riscv64 architectures. There is no intention to support proprietary platforms — this is a stated design choice, not an oversight.

C3 — "Evolution, not revolution"

Characterisation: C with a sensible haircut

Axiom: "Memory is bytes; pointers alias; but the syntax shouldn't fight you"

What it really is: C with obvious mistakes fixed.

C3 has full C ABI compatibility. You can mix C and C3 files in the same build with no friction. Contracts and slices work without libc. The compiler uses an LLVM backend.

C3 asks: what if we just... fixed the preprocessor and added slices? Sometimes the boring answer is correct.

Trade-off: Small community. Limited tooling. Pre-1.0.


Summary: The filter results

Language Tier C-ness Outcome
C Baseline ⭐⭐⭐⭐⭐ The thing we're trying to replace
Rust 1 ☆☆☆☆☆ Clear pass
Zig 1 ⭐⭐⭐⭐☆ Clear pass
Odin 1 ⭐⭐⭐⭐☆ Clear pass
Hare 1 ⭐⭐⭐⭐☆ Clear pass
C3 1 ⭐⭐⭐⭐☆ Clear pass
D 2 ⭐⭐☆☆☆ Conditional pass (-betterC)
Nim 2 ⭐⭐☆☆☆ Conditional pass (manual configuration)
V 2 ⭐⭐☆☆☆ Conditional pass (-gc none)
Swift 2 ⭐☆☆☆☆ Conditional pass (Embedded Swift)
C++ 3 ⭐⭐⭐⭐☆ Clear fail: companion to C, not successor
Go 3 ☆☆☆☆☆ Clear fail: mandatory GC/runtime
Carbon 3 ⭐⭐⭐⭐☆ Clear fail: wrong target (C++ successor)
Jai 3 ⭐⭐⭐⭐☆ Clear fail: cannot evaluate (not released)

Important distinction: The C-ness column measures semantic similarity to C's execution model. The tier column measures practical capability to occupy C's substrate role. These are independent axes. Rust scores zero on C-ness but passes all five substrate filters — it can replace C despite being nothing like it. Zig, Odin, Hare and C3 score high on both: they can replace C and feel familiar to C programmers.


Why the clear passes form the real contender set

The distinction between Tier 1 and Tier 2 matters.

Tier 1 (Clear Pass) languages (Rust, Zig, Odin, Hare, C3) are designed such that their distinctive features remain available in freestanding mode.

  • Rust's borrow checker works without std
  • Zig's comptime works without an OS
  • Odin's context system works freestanding
  • Hare's tagged unions work in kernels
  • C3's contracts and slices work without libc

Tier 2 (Conditional Pass) languages (D, Nim, Swift, V) can target C's substrate position, but doing so requires abandoning the features that differentiate them from C.

  • D without GC is just C with nicer syntax
  • Nim without its runtime is just a C code generator
  • Swift without reflection is just... less Swift
  • V without autofree is still figuring out what it is

This is the meaningful distinction:

Which languages let you be productive in their idiom while targeting the substrate?


What each Tier 1 language is actually trying to fix about C

Language Philosophy C's failure it targets Approach
Rust "Make invalid states unrepresentable" Memory safety Compile-time ownership tracking
Zig "No hidden control flow" Implicit behaviour, toolchain complexity Explicit allocators, drop-in C compiler
Odin "The joy of programming" Ergonomic scaling Context system, better defaults
Hare "Stability is a feature" Undefined behaviour, language drift Conservative redesign, frozen specification
C3 "Evolution, not revolution" Preprocessor, weak type safety Semantic macros, contracts, slices

This explains why they coexist: they disagree on what's wrong with C.


The real fault line

The true divide is not syntax. It is this:

Who controls memory? Languages
Programmer C, C++, Zig, Odin, Hare, C3, Carbon, Jai
Shared: Runtime + programmer D, Nim, V, Swift
Compiler Rust
Runtime Go

Rust is the only language where the compiler enforces memory correctness for safe code.

Everyone else either:

  • Trusts you (Unmanaged) — "Here's a gun, try not to shoot your foot"
  • Hides memory from you (Managed) — "What gun? There is no gun"
  • Does both depending on mode (Hybrid) — "Here's a gun, but we've hidden most of the bullets"

Rust says: "You can have the gun, but I'm going to check your paperwork first, and also during, and also after."


The philosophical spectrum

The five Tier 1 contenders can be placed on two axes.

Axis 1: Compiler protection — how much should the compiler constrain you?

Maximum protection                              Minimum protection
        |                                               |
      Rust -------- C3 -------- Odin -------- Hare -------- Zig
Enter fullscreen mode Exit fullscreen mode

Axis 2: Language complexity — how much machinery does the language have?

High complexity                                 Low complexity
        |                                               |
      Rust -------- Zig -------- C3 -------- Odin -------- Hare
Enter fullscreen mode Exit fullscreen mode

The philosophies track these positions:

Language Philosophy Protection Complexity Personality
Rust "Make invalid states unrepresentable" Maximum High The perfectionist who won't ship until it's right
Zig "No hidden control flow" Minimum Medium The pragmatist who reads the assembly output
Odin "The joy of programming" Medium Low The game dev who's sick of fighting the language
Hare "Stability is a feature" Low Minimal The greybeard who remembers when C was new
C3 "Evolution, not revolution" Medium Low The conservative who just wants C, but less annoying

The ecosystem reality

Language Philosophy Can replace C Is replacing C Where
Rust "Make invalid states unrepresentable" Yes Yes Linux kernel, Android, Windows components
Zig "No hidden control flow" Yes Yes Build toolchains, Bun runtime
Odin "The joy of programming" Yes Partially Game engines, developer tools
Hare "Stability is a feature" Yes Not yet Too early (released 2022)
C3 "Evolution, not revolution" Yes Not yet Too early, small community

C does not get replaced in theory. It gets replaced by where people migrate their code.


The real trajectory

C will not be "killed".

It will be:

  • Surrounded — Rust in Linux, Zig in toolchains
  • Absorbed — C3's C-mixing model
  • Constrained — new drivers in Rust, not C
  • Replaced in layers — userspace first, then kernel modules, then core kernel

Rust, Zig and Odin are already doing this. Hare and C3 show what a clean C could have been.


Conclusion

The story is not "C vs new languages".

It is:

Which languages can occupy the deepest layer of computing — the one C has held since 1973?

Fourteen languages were evaluated. Four failed outright or couldn't be assessed. Four passed conditionally. Five passed cleanly. One is the baseline.

Each survivor has a philosophy and an axiom:

Language Philosophy Axiom
C "Trust the programmer" Memory is bytes; pointers alias; mutation is unrestricted
Rust "Make invalid states unrepresentable" Memory is owned; aliasing is controlled; mutation is permissioned
Zig "No hidden control flow" Memory is bytes; pointers alias; but we will tell you when you mess up
Odin "The joy of programming" Memory is bytes; pointers alias; but the defaults should be sensible
Hare "Stability is a feature" Memory is bytes; pointers alias; but the language should be finished
C3 "Evolution, not revolution" Memory is bytes; pointers alias; but the syntax shouldn't fight you

The substrate is diversifying. Slowly, but measurably.

And the key insight:

Rust belongs to the C family only in grammar.
Zig, Odin, Hare and C3 belong to it in physics.

That is why Rust feels alien to C programmers, and Zig feels familiar.

They solve different problems.


Appendix A: Filter application detail

Language Freestanding Deterministic layout C interop No mandatory runtime Toolchain visibility
C
C++
Rust ✓ (no_std) ✓ (repr(C))
Zig
Odin
Hare Partial (QBE backend)
C3 ✓ (LLVM)
D ✓ (-betterC) ✓ (-betterC)
Nim ✓ (manual) Via C Via C ✓ (manual) Via C
V ✓ (-gc none) Via C Via C ✓ (-gc none) Via C
Swift ✓ (Embedded) Partial Partial ✓ (Embedded) Partial
Go Partial (cgo)
Carbon C++ focus
Jai ? ? ? ? ?

Appendix B: Complete language characterisation

Language Philosophy Characterisation Semantic family What it really is
C "Trust the programmer" The dangerous uncle who owns the house Unmanaged The alias-centric memory model
C++ "Zero-cost abstractions" C's midlife crisis Unmanaged C with objects, templates, and regrets
Rust "Make invalid states unrepresentable" Your compiler's disappointed parent Verified A safe systems language wearing C syntax
Zig "No hidden control flow" C's responsible older brother Unmanaged C with a compiler that cares
Odin "The joy of programming" C for people who ship video games Unmanaged Modernised C for large codebases
Hare "Stability is a feature" C if Ritchie had a time machine Unmanaged What C might have been with hindsight
C3 "Evolution, not revolution" C with a sensible haircut Unmanaged C with obvious mistakes fixed
D "C++ without the baggage" The language that tried to please everyone Hybrid C++ plus garbage collection
Nim "Write like Python, run like C" Python wearing a C costume Hybrid Python syntax on a C backend
V "Simple, fast, done" The language of bold promises Hybrid Fast-compile application language
Swift "Safety without sacrifice" Objective-C's attractive replacement Hybrid Apple's managed systems language
Go "Simplicity scales" Java in a hoodie Managed Systems infrastructure language, not substrate language
Carbon "C++ migration path" Google's C++ apology letter Unmanaged C++ interop successor
Jai "Game programmers know best" The language equivalent of "coming soon" Unmanaged Unknown (not released)

Appendix C: The four divergence paths from C

Path What they did Languages Summary
A: Keep C's physics Kept pointer aliasing, manual lifetimes, UB C++, Zig, Odin, Hare, C3, Carbon, Jai "C, but we fixed the obvious stuff"
B: Hide C's physics Replaced with GC, moving heaps, runtime checks Go "What if we just... didn't let you touch memory?"
C: Half-escape Raw pointers when asked, GC when not D, Nim, V, Swift "Have it both ways (and debug both sets of bugs)"
D: Replace the model Static aliasing constraints, compiler verification Rust "What if the compiler was your mum?"

Appendix D: Freestanding substrate vs systems infrastructure

Freestanding substrate programming:

  • You control the machine
  • No runtime beneath you
  • You handle interrupts, memory maps, hardware registers
  • Examples: kernels, drivers, firmware, bootloaders, language runtimes

Systems infrastructure programming:

  • You build infrastructure software
  • Runtime handles memory, scheduling, I/O
  • You handle requests, processes, orchestration
  • Examples: containers, networking tools, build systems, CLI utilities

Architectural compatibility with hard real-time / ISR constraints:

Language Compatible? Notes
C Yes Reference implementation
C++ Yes With care (no exceptions in ISR)
Rust Yes no_std mode
Zig Yes No runtime by default
Odin Yes Freestanding target
Hare Yes No libc by default
C3 Yes LLVM freestanding
D (-betterC) Likely Requires restricted mode
Nim (freestanding) Unclear Depends on stub implementation
V (-gc none) Unclear Pre-1.0, limited evidence
Swift (Embedded) Unclear Experimental mode
Go No Mandatory GC/runtime
Carbon Unclear Not yet positioned for this
Jai Unclear Not released

Go is excellent at systems infrastructure. It is structurally incapable of freestanding substrate work.


Last updated: January 2026.

Top comments (0)