Philosophy & Zen
Philosophy & Zen of Naso
The 4 Naso Axioms
These axioms are not guidelines—they are the mathematical bedrock on which Naso stands. Violate them, and the compiler rejects your code. No exceptions.
Axiom 1: Information is Physical
Linear resources (
[1]) enforce physical law—quantum no-cloning & entropy conservation are type rules, not runtime checks.
In classical computing, copying a pointer is free. In physics, cloning a quantum state is forbidden. Naso makes this distinction type-theoretic: a [1] Qubit cannot be copied, cannot be implicitly dropped, cannot be aliased. The type system is the physics engine. When you write let q = qalloc(), you are not “allocating memory”—you are asserting exclusive ownership of a physical two-level quantum system. The compiler enforces the no-cloning theorem at the type level. Entropy is not a metaphor here; [1] resources must be consumed exactly once, mirroring Landauer’s principle: erasure has a thermodynamic cost, and Naso makes you pay it explicitly via uncompute or consumption.
Axiom 2: Proofs Over Overhead
Compile-time Z3 proofs replace runtime checks, GC pauses, and dynamic tracing. If Z3 cannot prove it, the machine will not execute it.
Every array bounds check, every null check, every linear usage verification, every quantum uncomputation validity—these are not “safety features” that add overhead. They are proof obligations discharged by Z3 during compilation. The generated machine code contains zero runtime checks for verified properties. A [0] Proof carries exactly zero bits at runtime. A linear buffer inout compiles to a register-to-register move with no bounds checks, no reference counting, no borrow-tracking metadata. The overhead is shifted left—into the compiler, where it belongs.
Axiom 3: Deterministic Execution
No non-deterministic allocation, no hidden background runtime, no GC pauses. Every cycle is accounted for in the type system.
Naso has no garbage collector. No finalizers. No weak references. No background threads sweeping memory. Memory is managed by scope and quantity: [1] resources are deallocated at their single consumption point; [*] resources follow lexical scope (RAII); [0] resources never exist at runtime. Quantum ancilla are returned to $|0\rangle$ by verified uncompute blocks. The execution timeline is fully determined by the source code—there are no “stop-the-world” events, no allocation jitter, no priority inversions from a GC thread. This is not “real-time” as a feature; it is determinism as a consequence of the type system.
Axiom 4: Zero Hidden State
Uncompute intermediate quantum ancilla explicitly or fail the build. Bennett uncomputation is mandatory, not optional.
In quantum computing, every temporary qubit (ancilla) used during computation must be returned to the $|0\rangle$ state before it can be safely deallocated or reused. Failure to do so leaves entanglement “leaking” into the environment—decoherence that corrupts the entire computation. Naso makes this a compile-time requirement: the uncompute { ... } block is not syntactic sugar; it is a verified adjoint generator. The compiler proves (via Z3) that the block’s forward computation is unitary and that its adjoint correctly restores all ancilla to $|0\rangle$. If you omit the uncompute block, or if the block contains irreversible operations (measurement, classical control flow on quantum state), the build fails. There is no “runtime cleanup” for quantum state—physics doesn’t allow it, and Naso doesn’t pretend it does.
The Zen of Naso (10 Aphorisms)
These are not slogans. They are the distilled consequences of the four axioms, written to be internalized.
Linear is safe; unbounded (
[*]) is suspicious.[1]gives you the compiler’s full attention.[*]says “I promise not to break things.” The compiler believes[1]; it merely tolerates[*].
If Z3 cannot prove it, the machine will not execute it.
- Not “might not.” Will not. The verification condition is the gate.
UNSAT= green light.SAT/UNKNOWN= red light. No human override.
- Not “might not.” Will not. The verification condition is the gate.
Memory leaks waste bytes; quantum state leaks break reality.
- A classical leak is a bug. A quantum leak (dropped entanglement) is a physical error that propagates exponentially. Naso treats both as type errors, but the quantum one gets the stricter error code (
NASO-UNC-001).
- A classical leak is a bug. A quantum leak (dropped entanglement) is a physical error that propagates exponentially. Naso treats both as type errors, but the quantum one gets the stricter error code (
Explicit uncomputation is cheaper than a garbage collector.
- A GC pauses the world to find garbage.
uncomputeknows exactly what to clean and when, because the type system tracked it. The adjoint is free—it’s just the forward circuit run backward.
- A GC pauses the world to find garbage.
Pass by
inoutgrants temporary exclusive mutation rights, not shared confusion.inout x: [1] Tmeans: “I borrowxexclusively, mutate it, and return it. No one else sees it. No one else touches it.” This is stronger than&mut T(which allows reborrowing) and safer thanT*(which allows aliasing).
Affine loops bound time; QTT bounds space.
- Polyhedral schedules give you provable iteration counts and dependence-free parallelism. QTT quantities give you provable memory footprints and resource lifetimes. Together, they bound the entire execution envelope.
Pointers alias problems; values isolate truth.
- A pointer is a promise that can be broken. A value (especially a
[1]linear value) is a fact enforced by the type system. Naso defaults to values. Pointers exist only instd::memfor FFI, and they carry[1]or[0]quantities.
- A pointer is a promise that can be broken. A value (especially a
A compile-time diagnostic today prevents a physical decoherence disaster tomorrow.
- The cost of a
NASO-UNC-002error at compile time is seconds. The cost of the same bug on a 1000-qubit processor is a failed experiment, wasted beam time, and potentially damaged hardware. Naso makes you pay the small cost upfront.
- The cost of a
No hidden runtime, no dynamic tracing, no surprises.
- What you see in the source is what executes. No JIT compilation. No dynamic linking surprises. No reflection. No
Anytype. The binary is a pure function of the source and the target triple.
- What you see in the source is what executes. No JIT compilation. No dynamic linking surprises. No reflection. No
Hardware is physical—your type system should be too.
- Qubits are physical. Cache lines are physical. DRAM rows are physical. ALU pipelines are physical. A type system that ignores physics (aliasing, copying, dropping, unbounded loops) is a fiction. Naso’s type system models the hardware: linear for unique ownership, bounded for finite resources, erased for proofs, polyhedral for structured parallelism.
Explicit Non-Goals
Naso achieves its guarantees by refusing to be certain things. This is not omission—it is architectural discipline.
| Non-Goal | Reason |
|---|---|
| No GUI/Web CRUD Bloat | Naso targets compute kernels, runtimes, and hardware abstraction layers. HTTP handlers, DOM manipulation, and ORM layers belong in languages with GC and dynamic dispatch. |
| No Dynamic Runtime | No JIT, no interpreter, no REPL (in the traditional sense), no dynamic code loading. All code is ahead-of-time compiled and verified. |
| No Implicit Coercion | No T → *T, no [1] T → [*] T, no integer widening without explicit cast. Every quantity transition is explicit in the source. |
| No Untyped Raw Pointers | *mut T and *const T exist only in std::mem::raw behind a #[unsafe] gate for FFI. They carry no safety guarantees and are not part of the safe language. |
| No Exception Handling | Panic = immediate abort (configurable). No stack unwinding, no catch_unwind. Error handling is via Result<T, E> and Option<T>—verified by Z3 for exhaustive matching. |
| No Reflection / Introspection | Types are erased at compile time. No TypeId, no Any, no runtime type information. Generic monomorphization is the only polymorphism. |
| No Incremental Compilation (Semantic) | Builds are fast because the compiler is simple, not because it caches partial semantic analysis. The verification step is always fresh. |
| No “Unsafe” Escape Hatch in Safe Code | #[unsafe] blocks exist only for FFI and inline assembly. They do not exist in the core language. You cannot “opt out” of QTT/MVS in a function body. |
Frequently Denied Requests (FDR) Callout Box
FDR-001: Request for any or void* untyped pointers → Status: Permanently Denied. Z3 solver experienced existential dread and refused to generate SMT-LIB2 output.
FDR-002: Request to drop entangled ancilla qubits implicitly → Status: Permanently Denied. Schrödinger’s cat called our legal team.
FDR-003: Request for background garbage collector thread → Status: Permanently Denied. Non-deterministic execution pauses violate the laws of physics and engineering decency.
FDR-004: Request to suppress compiler errors on linear variable reuse → Status: Permanently Denied. The quantum no-cloning theorem is not a toggleable compiler flag.
FDR-005: Request for unsafe { } blocks in application code → Status: Permanently Denied. If you need unsafe, you are writing FFI glue, not Naso. Put it in a #[unsafe] extern block.
FDR-006: Request for runtime type reflection (type_of, Any) → Status: Permanently Denied. Types are proofs. Proofs don’t exist at runtime. [0] erasure is not negotiable.
FDR-007: Request for implicit integer widening (i32 → i64) → Status: Permanently Denied. Quantity [N] bounds depend on exact bit-width. Widening changes the polyhedral domain.
FDR-008: Request for async/await with hidden state machines → Status: Permanently Denied. Async state machines allocate. Allocation requires [1] or [*]. Naso makes the allocation explicit. Write your own state machine with linear types.
FDR-009: Request for global mutable state → Status: Permanently Denied. Globals are [*] by default (shared, classical). Mutable globals require static mut which is #[unsafe] only. MVS inout is the only safe mutation primitive.
FDR-010: Request to “just warn” on linear type violations → Status: Permanently Denied. A warning implies the code might run. Linear violations will corrupt state. The compiler errors. Period.
Closing Thought
“The purpose of a type system is not to prevent errors. The purpose of a type system is to make invalid programs unrepresentable. Naso extends this principle to quantum state, hardware topology, and physical law.”
— Naso Design Manifesto, §1.0