Rust made one axis visible: memory. Janus makes the larger claim. Memory, concurrency, side effects, authority, termination, preconditions, compile-time behavior, and determinism should be visible to the compiler; not buried in discipline, comments, or tribal folklore. Write what your code does. Let the compiler prove what it cannot do. Eight axes. One doctrine. Systems programming without hidden lies.
v2026.4.8
Three-phase sigil system: § (compile-time), $ (extraction), @ (metadata). One sigil, one phase — no cross-world aliasing. Old $size_of migrates to §size_of (W5001 deprecation). :script profile ships: implicit defaults, top-level statements, $1/$2/$* positional sugar, AOT-cached execution. Every .jans program desugars mechanically to legal :core — throwaway now, promote later, never rewrite. Language Reference v2026.4.8: the single-source doctrine. Two Structural Laws codified — do...end for flow, { } for data. Memory Authority Types (Buffer, OwnedSlice[T], Arena) ratified. No ambient allocators. Conversion trichotomy in std.conv: widen[T] (total), to[T] (fallible), truncate[T] (lossy) — zero-allocation, mechanism over policy.
v2026.4.7
First sovereign math library: 22 native polynomial trig functions replace graft c "math.h" entirely. Zero C dependency. All comptime-eligible. FDLIBM minimax polynomials, Cody-Waite range reduction. Integer trig fast path: std.math.trig_int – pure Janus, zero FPU, for BitNet × PolarQuant multiplication-free inference. Polar embeddings: std.compute.polar – N-dimensional hyperspherical coordinates, the first polar embedding type in any systems language.
v2026.3.31
..defaults — Match Overhaul — Generics — C FFI
Struct Initialization Completeness (Law 10): ..defaults spread – all fields required unless you opt in. Eliminates silent bugs when struct fields are added. Match overhaul: else replaces _ as match wildcard (one symbol, one meaning). .Variant patterns type-inferred from match subject. Also: Zig 0.16 migration complete, graft c / graft zig FFI, generics with monomorphization, LLVM codegen fixes, dependency cache hardening.
v2026.3.22
Janus programs can now span multiple files. use math discovers, parses, and links math.jan automatically. Qualified calls (math.add(21, 21)) resolve through module-aware lowering. Selective imports (use math { sin, cos }), aliases (use crypto.hash as h), relative imports (use .sibling). Every module gets a BLAKE3 content-addressed CID – identity is content, not filesystem path. Cycle detection prevents infinite recursion. ModuleIndex tracks path→CID mappings. 36 new tests across 4 suites. Green build: 1,771 tests passing.
v2026.3.23
janus fmt ships — canonical formatter with 34 idempotency-verified tests. --check mode with line-by-line diff output for CI. Dogfooded on 1,056-line production file. janus build reads janus.lock — compiles dependencies from local registry, links into binary. :service profile fully green — nested using verified at 3 levels. Hinge integration: deduplicated modules, proper KDL serialization, transitive lockfile. println compiler fix. Formatter specification committed.
v2026.3.18
First-class compile-time evaluation. comptime do...end blocks, §size_of/§type_info compile-time sigil builtins. Checked arithmetic. 14 builtins. 1,700+ tests.
v2026.3.15
+1,500 line parser overhaul. ++ concatenation operator. @ builtin prefix. Struct methods, const decls, default field values. Anonymous enums with backing types. fn alias for func. Monomorph cache memory leak eliminated. i32→i64 type widening for string and array ops. Hinge registry HTTP scaffold.
v2026.3.14
Pure Janus ZSTD codec (RFC 8878, zero dependencies). Native TLS backend via std.net.tls. HTTPS wired into HTTP client. std.gtp and std.hinge stdlib modules. Graf integration for Hinge — publish, lockfile migration, graf.lock.json. Supertrait syntax and oracle. 236-test HTTP stack.
v2026.3.12
:service profile pipeline complete. std.crypto with L1 SoulKey identity. SBI module (std.sbi). Base32 and KDL encoders. Socket primitives. Sovereign Binary Interface bridge. Capsule structure for crypto, hash, and time.
v2026.3.10
Documentation as structured data in the ASTDB. janus doc generates Markdown from /// comments. janus query --doc filters by predicate. Hinge sovereign supply chain (25 modules, 18K LOC). Generic monomorphization, supertrait propagation, std.core.conv.
Every design decision in Janus flows from three immutable principles.
The source code, the intermediate representation, and the final binary all tell the same story. No hidden transformations. No magic. You read the code; you know what it does.
The compiler provides levers; not opinions. Janus gives you the simplest correct mechanism and lets you decide the policy. No defaults that secretly optimize against your intent.
If something is expensive, the syntax makes it visible. Dynamic dispatch costs cycles? You see &dyn Trait. Allocation happens? You see the allocator. The cost is always in the code.
Beautiful syntax. Honest semantics. No exceptions; no sugar in :core.
// The simplest honest program. func main() do println("Hello, Sovereign World.") end
// Verbose? Never. Janus is as terse as you want it to be. func clamp(x: i64, lo: i64, hi: i64) -> i64 = match x { _ if x < lo => lo, _ if x > hi => hi, _ => x } func is_prime(n: i64) -> bool = n > 1 and for 2..isqrt(n)+1 do |i| n % i != 0 end func fizzbuzz(n: i64) -> string = match (n%3, n%5) { (0,0) => "FizzBuzz", (0,_) => "Fizz", (_,0) => "Buzz", _ => itoa(n) } // Same language. Same compiler. Your call.
trait Drawable { func draw(self) -> i32 } struct Circle { radius: i32 } impl Drawable for Circle { func draw(self) -> i32 do return self.radius * 2 end } // Dynamic dispatch. Cost is visible. func render(d: &dyn Drawable) -> i32 do return d.draw() end
func parse_port(s: string) -> i32 ! ParseError do let n = to_int(s) catch |e| do fail ParseError.InvalidNumber end if n < 0 or n > 65535 do fail ParseError.OutOfRange end return n end
func fetch_all(urls: []string) do nursery |n| do for url in urls do n.spawn(async fetch(url)) end end // All tasks complete or cancel here. end
const Ed25519 = std.crypto.sign.Ed25519; pub const SoulKey = struct { seed: [32]u8, public: [32]u8, pub fn sign(self: *const SoulKey, msg: []const u8) [64]u8 do const kp = Ed25519.KeyPair .generateDeterministic(self.seed) catch return .{0} ** 64; return kp.sign(msg, null).toBytes(); end }; // Zig types. Janus syntax. One binary.
// Sovereign package manifest. project { name "myservice" version "1.0.0" profile "service" } dependencies { crypto "^2.1.0" // Verified supply chain } // Ed25519 signed. BLAKE3 content-addressed. // Publish: janus pkg publish --key id.key
Janus compiles through Zig to LLVM to native. Not a transpiler – one fused compilation unit. Every stage is inspectable.
Start simple. Scale to sovereign. No rewrite required.
M:N fiber scheduler. Structured scopes. CSP channels. No function coloring. No runtime bloat.
// Structured concurrency + CSP channels. // Every task completes or cancels at nursery end. async func main() do let ch = channel(10) nursery do spawn producer(ch) spawn consumer(ch) end // both tasks guaranteed done here end func producer(ch: Channel) do for i in 0..100 do ch.send(i) end ch.close() end func consumer(ch: Channel) do while not ch.isClosed() do let val = ch.recv() println(val) end end
nursery guarantees every spawned task completes or cancels before the scope exits. No orphaned goroutines. No forgotten futures. The compiler enforces the lifetime.
No async/await viral infection. Sync and async code share the same grammar. The scheduler decides; the programmer writes intent.
Capability-Budgeted Cooperative M:N with work-stealing. Fibers multiplex over OS threads. The main thread participates as a worker – zero wasted cores.
Everything listed here compiles, runs, and is tested. Today.
Traits, impl blocks, static + dynamic dispatch with vtables. Fat pointers for &dyn Trait. Default methods. Complete polymorphism system.
Nurseries, spawn, await, select, channels. M:N fiber scheduler with 5,249 lines of battle-tested runtime. CSP done right.
Code stored as a semantic database with content-addressed identity. AI and tooling can query structure, not parse text. UUID-stable refactoring.
T ! E error types, fail, catch, try. Errors are values, not exceptions. The type system tracks what can fail.
Zero-capture, captured, mutable capture. Three clean closure types with explicit capture semantics. No hidden allocations.
Janus compiles through Zig – not to it, not beside it. use zig and you write Janus syntax with Zig’s type system, crypto, I/O, and allocators. No FFI. No bindings. Same binary. Ed25519 in do..end blocks.
comptime do...end blocks, §size_of/§type_info compile-time sigil builtins, inline for/inline switch. Checked arithmetic, resource-limited evaluation. Profile-gated — :core gets basics, :service gets introspection. The § sigil is the canonical form for compile-time evaluation.
Buffer, OwnedSlice[T], and Arena make ownership explicit in the type system. Every allocator is visible, every destructor is explicit. No hidden deallocators, no ambient allocators. The type says what owns memory.
match on integers, enums, tagged unions. Exhaustiveness checking. The right arm fires; the rest don't exist.
Monomorphized generics. Scoped Impl Resolution — no orphan rules. Julia-style multi-dispatch on ALL arg types. 13K LOC dispatch engine.
Sovereign Binary Interface — zero-encoding where wire = memory. Decode is a pointer cast, not deserialization. BLAKE3 Merkle proofs for field-level verification. Comptime schema fingerprinting. No protoc, no IDL, no codegen.
Sovereign supply chain. Ed25519 + Dilithium3 hybrid signatures, BLAKE3 content addressing, Chapter federation, witness consensus, trust graphs, DMP gossip, transparency ledger. 25 modules, 18K LOC.
Documentation is data, not decoration. /// comments are parsed into structured columnar arrays — queryable by predicate. janus doc generates Markdown. janus query --doc finds undocumented, deprecated, or incomplete declarations. Docs survive renames via CID identity.
janus fmtCanonical formatter. One style. No arguments. janus fmt file.jan formats in-place; --check mode exits non-zero with a line-by-line diff for CI. 34 idempotency-verified tests. Dogfooded on 1,000+ line production code. A language without fmt tolerates arguments about whitespace. Janus doesn’t.
"A language is not a tool. It is a discipline."
Janus credits Hylo’s lineage honestly, then carries the model into actors, profiles, tensors, and the sovereign stack.
Janus did not invent Mutable Value Semantics from nothing. Hylo, formerly Val, pushed this design space into serious language-theory territory: value-oriented programming, mutation without spooky action at a distance, compiler-enforced exclusivity, and function parameters that describe intent instead of exposing references.
Dave Abrahams, Dimi Racordon, and the Hylo team proved the core thesis: you can keep local reasoning and still mutate in place. You can move borrow reasoning out of the programmer’s hands and into the compiler, where it belongs.
The programmer should describe the deed. The compiler should build the bridge.
view — read thisedit — mutate thistake — consume thismake — initialize this
Hylo expresses Mutable Value Semantics through let, inout, sink, and set. Janus proposes its own surface for the same moral center: function signatures state intent, not ABI machinery.
Hylo validates the paradigm: Mutable Value Semantics, projections instead of exposed references, and compiler-side exclusivity. Janus cites the lineage instead of pretending the idea fell from orbit.
Reference capabilities, affine resources, actors, profile-gated semantics, tensor descriptors, and raw pointer preservation at FFI boundaries. Same foundation; different war.
The analysis still exists. The compiler must prove exclusivity and reject unsafe aliases. What disappears is the programmer’s obligation to write lifetime riddles by hand.
Janus did not make the borrow checker nicer.
It made the programmer’s borrow checker unemployed.
Mutable Value Semantics for sovereign systems programming.
A systems language should not merely prevent use-after-free. It should expose the whole operational surface: what code may mutate, share, touch, consume, allocate, authorize, terminate, and replay.
| Axis | Janus mechanism | Compiler-visible question |
|---|---|---|
| Memory | Mutable Value Semantics | What does this function do with each value? |
| Concurrency | Reference capabilities + nurseries | Who may share, send, mutate, or isolate data? |
| Side effects | Algebraic effect rows | What world-contact can this call graph perform? |
| Authority | Resource capabilities + manifests | Which resources may this binary touch? |
| Termination | Total functions | Does this computation finish on all paths? |
| Preconditions | Refinement types | What must be true before this value is valid? |
| Compile-time | Comptime trichotomy + comptime effects | What runs during build, and with what authority? |
| Determinism | Deterministic effect discipline | Will the same inputs produce the same outputs under replay? |
This is the Janus thesis: Rust proved programmers would accept compiler-enforced discipline for memory. Janus asks the obvious next question: why stop there? Read the full thesis →
Green where we deliver. Red where we don't. Yet.
| Feature | Janus | Go | Rust | Zig |
|---|---|---|---|---|
| Trait System | ✓ Traits + impl, static + dynamic dispatch | ✓ Interfaces | ✓ Traits + impls | ✗ Duck typing |
| Generics | ✓ Monomorphized — identity[T] compiles natively | ✓ Since Go 1.18 | ✓ Full generics + traits | ✓ Comptime generics |
| Multi-Dispatch | ✓ Julia-style — resolves on ALL arg types | ✗ Single dispatch only | ✗ Single dispatch (self only) | ✗ No dispatch system |
| Scoped Impl Resolution | ✓ No orphan rules — 5-stage SIR pipeline | ✗ No trait system | ✗ Orphan rule restricts impls | ✗ No trait system |
| Structured Concurrency | ✓ Nurseries — no orphan tasks | ✗ Goroutines leak freely | ✗ tokio::spawn is unstructured | ◐ Has async frames |
| Error Handling | ✓ Error unions T ! E | ✗ if err != nil boilerplate | ✓ Result<T,E> + ? operator | ✓ Error unions + try |
| Syntax Clarity | ✓ do/end blocks, clean grammar | ◐ Simple but verbose | ✗ Lifetime annotations, turbofish | ◐ Comptime complexity |
| Native Compilation | ✓ LLVM via Zig toolchain | ✓ Go compiler | ✓ LLVM | ✓ LLVM + self-hosted |
| Zig Stdlib Access | ✓ native — one compilation unit, not FFI | ✗ CGo overhead | ✗ Separate FFI | ✓ Native |
| Enum/Union Types | ✓ Tagged unions + match | ✗ No sum types | ✓ enum + match | ✓ Tagged unions |
| Compile-Time Evaluation | ✓ comptime blocks, $builtins, inline for/switch | ✗ No comptime | ◐ const fn (limited) | ✓ Full comptime |
| Sovereign Packages | ✓ Hinge — signed, federated, post-quantum | ◐ go mod (centralized) | ◐ crates.io (centralized) | ✗ No package manager |
| Binary Wire Format | ✓ SBI — zero-encoding, BLAKE3 Merkle proofs | ◐ protobuf (varint encode/decode) | ◐ serde (ecosystem, not built-in) | ✗ No standard wire format |
Janus v2026.3.23 — :core + :service profiles complete. janus fmt canonical formatter. janus build reads lockfile and compiles dependencies. Hinge sovereign package manager with full local lifecycle. One Language, Two Faces: Janus syntax fused with Zig’s type system and stdlib in a single compilation unit. No FFI. No bindings. Multi-dispatch, scoped impl resolution, trait-bounded generics, sovereign federated packages, and queryable documentation are unique to Janus.
Fixed-size structs, same architecture. Zero encoding. Zero parsing. Zero copies.
| Dimension | SBI | SSZ | Protobuf | FlatBuffers | Cap'n Proto |
|---|---|---|---|---|---|
| Encode Cost | ✓ Zero (memcpy identity) | ◐ LE pack + offsets | ✗ Varint encode per field | ◐ Vtable + buffer build | ◐ XOR + offset calc |
| Decode Cost | ✓ Pointer cast (O(1)) | ◐ Offset walk | ✗ Full varint decode | ◐ Vtable lookup | ◐ Deref + XOR |
| Wire = Memory | ✓ Exact identity | ✗ Packed, no alignment | ✗ Varint encoding | ◐ Structs only (LE) | ◐ Nearly (XOR defaults) |
| Merkle Proofs | ✓ BLAKE3, field-level | ✓ SHA-256, generalized | ✗ None | ✗ None | ◐ Flat hash only |
| External Tooling | ✓ None — compiler is schema | ✓ None (implicit) | ✗ protoc + plugins | ✗ flatc + plugins | ✗ capnpc + plugins |
| Schema Evolution | ✗ None (by design) | ✗ None formal | ✓ Field numbers | ◐ Tables only | ✓ Append-only |
| Variable-Length Data | ◐ Planned (:service) | ✓ Offset tables | ✓ LEN wire type | ✓ Vectors, strings | ✓ Lists, text |
| Language Support | ◐ Janus + Zig | ◐ ~8 (Ethereum) | ✓ 30+ languages | ✓ 14+ languages | ✓ ~16 languages |
SBI is not a general-purpose serialization framework. It is the fastest possible wire format for a constrained domain: same-architecture peers, fixed-size structs, cryptographic type identity. Schema evolution and variable-length data trade correctness for flexibility — SBI chooses correctness. Full SBI documentation →
You know the drill. Requires Zig 0.16.x.
# Clone and build (requires Zig 0.16.x) git clone https://git.sovereign-society.org/janus/janus-lang.git cd janus-lang && zig build # Scaffold a new project ./zig-out/bin/janus init myproject cd myproject # Build and run ../zig-out/bin/janus build src/main.jan main && ./main # "Hello from Janus!" # 1,700+ tests passing zig build test
Green means working code with passing tests. Yellow means specified. Blue means dreamed.