Cyr is the native dialect of Cyra — AOT-compiled via LLVM, from servers down to a bare MCU. No VM, no GC. The language machines write, now on the metal.
This page shares the first ideas, the inception philosophy, and the expectations for Cyr. The name, the trunk/branch relationship, the runtime and CLI names, and a set of keystone decisions are locked — but Cyr is not yet shipping. What you read here is a charter, not a release.
Why Cyr exists
Cyra is excellent at what the BEAM is excellent at: concurrent, fault-tolerant, hot-reloadable systems. But whole classes of work live below that line. Today a developer who hits the wall must drop to C, Rust, or Zig and leave the language entirely. Cyr is the escape hatch that keeps you in the family.
Cyr compiles ahead-of-time to native object code via LLVM — no VM, no JIT. A self-contained binary that runs on a Tier-1 platform with nothing installed.
cyrtA small runtime linked into every binary — allocator, panic handler, intrinsics. Targeted at low hundreds of kilobytes, not megabytes. Embedded and WASM-plausible.
@external(c, "...") is the single native interop surface. Call
C and be called by C with full signatures, explicit widths, and explicit
nullability — no hand-written glue.
switch-only flow, Option/Result,
explicit types — ~85% identical grammar to Cyra. The skill and the
source cross the managed/native boundary.
One language, two dialects
One grammar, one semantics core, two backends — the way C has a hosted and a freestanding implementation. The trunk is the shared grammar; the two branches diverge only where the runtime model forces them to.
// the BEAM dialect
Warm and managed. Runs on a machine.
pid / ref / port:erlang.* FFI · Cyra.* stdlib// the native dialect
Bare metal. Is the machine code.
ptr<T>, @external(c, "...")bigint opt-incyrt runtime · Cyr.* stdlibSystems & OS reach
Cyr explicitly targets low-level systems and OS development — up to and
including an init/PID 1, daemons, drivers, and freestanding
bare-metal code. The harder the profile, the more the language gets out of the
way. Cyr's reach is organized into three execution profiles.
app · daemon · CLI
A normal native program on a full OS. The whole stack is available, and
cyrt uses the OS heap and OS threads.
init / PID 1 · minimal static binary
A kernel is present but userland is minimal. PID 1 should not drag a full libc — a thin direct-syscall layer talks to the kernel.
kernel · bootloader · firmware · ISR
No OS at all. You bring the allocator; there are no threads, no libc,
no unwinding. Inline asm, volatile/MMIO, atomics, custom
entry points.
See it in action
A driver fragment with C23 FFI, packed layout, Option instead of
null, and tail recursion that runs in constant stack — all in familiar
Cyra syntax.
module Sensor.Driver {
use Cyr.Result;
// C23 FFI — the single native interop surface
@external(c, "read_register")
fn read_register(addr: ptr<u32>) -> u32;
@repr(packed)
struct Reading { id: u16; value: i32; }
// switch-only flow; Option<T> for absence, never null
pub fn decode(raw: u32) -> Option<Reading> {
switch raw {
0 => None;
_ => Some(Reading { id: 1, value: raw as i32 });
}
}
// guaranteed constant stack — TCO holds at the CIR layer
fn sum(xs: list<i64>, acc: i64) -> i64 {
switch xs {
[] => acc;
h :: rest => sum(rest, acc + h); // i64 traps on overflow
}
}
@entry
pub fn main() -> i32 { 0; }
}
What is already locked
Cyr begins from the premises Cyra already settled, plus a set of one-way doors ratified by the philosophy council at inception. These are the expectations Cyr commits to.
i64 default; arithmetic traps by default.
wrapping, saturating, and bigint
are explicit opt-ins.
nil is retired from non-Option types. Null lives
only behind ptr/any at the C wall.
Tail-position recursion — including mutual recursion — runs in constant stack. A semantic guarantee at the CIR layer, not LLVM faith.
Memory is ARC + opt-in arena + weak. Safety is relocated to
compiler defaults, not author-written lifetime annotations — the
right call for an LLM-authored corpus.
unsafe
Raw ptr<T> deref and any down-casts live
only inside unsafe — greppable and auditable.
Cyr.* stdlib
Cyr rewrites its standard library natively. Portability lives in the
grammar, not the library names — a use line is always
honest about its dialect.
Honest positioning
Cyr is not "Cyra 2.0" and does not diverge in syntax. It is one language with two backends — not two languages competing.
Cyr ships as part of the same project — same tooling, same community — not a rival product with its own identity.
pid, ref, port, spawn,
receive, send are removed. Anything actor-like
is a library, not a language primitive.
Cyr is for the people who already love Cyra and now want to write the layer underneath their applications — not a pitch to the general systems-programming public.
Design philosophy
"Source and skill continuity"
Peirce's pragmatic maxim is Cyr's test: what concrete difference does Cyr make that "Cyra plus just use C" does not? The answer — continuity of source and skill across the managed/native boundary — governs every design choice.
"Grammar shared, library honest"
The dialects share ~85% of their syntax — the real transferable asset. They deliberately do not share library names: coherence belongs to syntax and CLI; honesty belongs to the namespace.
"Twenty-one philosophers, one charter"
Aristotle's Four Causes frame the effort; Popper names what would falsify success; Kant's antinomies keep the council honest. Eighteen open design domains were read by all twenty-one, and the keystone decisions ratified — the council runs as organon, open on GitLab.