Compile-Time Evaluation
Updated for v2026.4.8. Compile-time builtins now use the canonical § sigil; legacy $-prefixed forms warn with W5001.
Compile-Time Evaluation (SPEC-043)
Section titled “Compile-Time Evaluation (SPEC-043)”Janus provides first-class compile-time evaluation primitives. Code marked comptime executes during compilation — the results are baked into the binary as constants. No runtime cost.
Design principle: The
§meta-sigil makes compiler-phase operations visually distinct from runtime functions. You always know what runs when.
Comptime Blocks
Section titled “Comptime Blocks”Execute a block of statements at compile time:
comptime do let table = build_lookup_table(256)endFor single expressions:
const SIZE = comptime { calculate_optimal_size(PAGE_SIZE) }The § Meta-Sigil
Section titled “The § Meta-Sigil”All compiler builtins use the § prefix. This is not decoration — it signals “this executes in the compiler, not in your binary.”
:core Builtins (Available Everywhere)
Section titled “:core Builtins (Available Everywhere)”| Builtin | Signature | Purpose |
|---|---|---|
§size_of | §size_of(Type) -> i64 | Size of a type in bytes |
§align_of | §align_of(Type) -> i64 | Alignment requirement |
§is_integral | §is_integral(Type) -> bool | True for integer types |
§is_float | §is_float(Type) -> bool | True for floating-point types |
§fmt | §fmt(args...) -> string | Comptime string construction |
§compile_error | §compile_error(msg) -> never | Halt compilation with message |
:service Builtins (Type Introspection)
Section titled “:service Builtins (Type Introspection)”| Builtin | Signature | Purpose |
|---|---|---|
§type_info | §type_info(Type) -> TypeInfo | Full type metadata |
§type_name | §type_name(Type) -> string | Human-readable type name |
§type_id | §type_id(Type) -> u64 | Stable hash identifier |
§fields | §fields(Type) -> []string | List of field names |
§has_field | §has_field(Type, name) -> bool | Check field existence |
§has_decl | §has_decl(Type, name) -> bool | Check declaration existence |
§field_type | §field_type(Type, name) -> string | Type of a named field |
§field | §field(value, name) -> T | Access field by name |
Comptime Parameters
Section titled “Comptime Parameters”Functions can require arguments to be known at compile time:
func make_array(comptime N: usize, fill: i64) [N]i64 do var result: [N]i64 = undefined inline for 0..N |i| do result[i] = fill end return resultend
// N is resolved at compile time -- the loop is fully unrolledconst arr = make_array(4, 0)Inline Control Flow
Section titled “Inline Control Flow”inline for
Section titled “inline for”Unrolls the loop body at compile time. Each iteration becomes straight-line code in the binary:
inline for fields |name| do println(name)endinline switch
Section titled “inline switch”Evaluates the discriminant at compile time and emits only the matching branch:
inline switch §type_info(T).kind { .Int => handle_int(), .Float => handle_float(), _ => §compile_error("unsupported type"),}if comptime
Section titled “if comptime”Conditional compilation — dead branches are eliminated entirely:
if comptime §is_integral(T) do // This code only exists in the binary when T is an integer type optimized_int_path()else generic_path()endProfile Capability Matrix
Section titled “Profile Capability Matrix”Comptime features are progressively disclosed through profiles:
| Capability | :core | :service | :sovereign |
|---|---|---|---|
comptime do...end blocks | Yes | Yes | Yes |
comptime parameters | Yes | Yes | Yes |
§size_of, §align_of | Yes | Yes | Yes |
§is_integral, §is_float | Yes | Yes | Yes |
§fmt, §compile_error | Yes | Yes | Yes |
§type_info, §type_name | — | Yes | Yes |
§type_id, §fields | — | Yes | Yes |
§has_field, §has_decl | — | Yes | Yes |
| Comptime allocation | — | — | Yes |
Resource Limits
Section titled “Resource Limits”The comptime evaluator enforces hard limits to prevent runaway compilation:
| Resource | Limit |
|---|---|
| Evaluation steps | 1,000,000 |
| Memory | 256 MB |
| Recursion depth | 1,000 |
Exceeding any limit produces a clear compile-time error — not a hang or crash.
Arithmetic Safety
Section titled “Arithmetic Safety”Comptime arithmetic uses checked operations. Integer overflow, negative shifts, and out-of-range shift amounts produce compile-time errors — not silent wrapping. This aligns with Janus’s Syntactic Honesty doctrine: if the math is wrong, the compiler tells you.
// Compile error: IntegerOverflowconst bad = comptime { 9223372036854775807 + 1 }
// Compile error: IntegerOverflow (shift amount out of range)const also_bad = comptime { 1 << -1 }Practical Example: Lookup Table Generation
Section titled “Practical Example: Lookup Table Generation”func hex_char(nibble: u4) u8 do const table = comptime do var t: [16]u8 = undefined inline for 0..10 |i| do t[i] = '0' + i end inline for 0..6 |i| do t[10 + i] = 'a' + i end t end return table[nibble]endThe lookup table is computed once during compilation. At runtime, hex_char is a single array index.
Next: Profiles System — understand how comptime capabilities scale across profiles.