Open and answer this issue on GitHub.
ready · opened 2026-10-28 · updated 2026-10-31 · 2 comments
Nikaia has no macro system (Part II 10.1, ADR-304 D1); code that depends on something known while the program is built is ordinary code that runs earlier. Until now that produced code in one place: a loop over T::fields, unrolled once per type (ADR-304). A loop over a build-time value is a run-time loop over a constant table (for x in TABLE.iter(), checked on 0.0.1225). A library that wants code shaped by a value - a regular expression’s automaton (#673), a route pattern, a layout - had no way to say so short of a special case in the compiler.
comptime as a contract and comptime? as where it is known on a parameter, self included; no construct that asks whether a value is known (it would let one value give two answers); the loop’s mark as an attribute, @unroll - not comptime for (it reads as if the body ran while building), not inline for - deciding the stage of the loop variable, not the machine code; @unroll(up_to: N) instead of strict: false, the body checked both ways; a result type computed from comptime parameters.ADR-specialization-1; specification Part I 4.6 (comptime?, computed result type), Part II 10.3 (@unroll, decided branches), Part III (NK1304, NK1305).
comptime? parameter makes a copy of the function per build-time value a call gives it, and leaves the function as written for the rest; a value is known by rule (a comptime binding, a literal, a comptime/comptime? parameter in its copy, a part of one, a call the build may run), never because a let was folded.@unroll before a for makes the loop variable a build-time value in every turn (NK1304 where the list is not one); in the function as written, a list from a comptime? parameter is an ordinary loop.@unroll(up_to: N) unrolls a list of at most N elements and leaves a longer one a loop; the body is checked both ways (NK1305).if or match on a value known in this copy and turn is decided while building. D5: checked per turn, every turn counts against the budget (NK1152). D6: no stage query. D7: a result type may be computed from comptime parameters. D8: --comptime reports.comptime parameter of a function, emitted once per value): evaluating a value per copy while building is the part this record shares with it.if s == k chain per state - against the same DFA as a table loop and against regex-automata’s dense DFA; callgrind instruction counts, same output first. If the chain does not become a jump table, match arms written from a list become a question of their own (ADR-specialization-1 §4).comptime? on parameters and self: copies per known value keyed by the value, the function as written for the rest; the ledger carries the mark across packages; NK1305 for such a parameter where only a build-time value is allowed.@unroll before a for (the first attribute before a statement): the list evaluated per copy, each turn a block with the element bound as a constant, continue/break through labelled Rust blocks, nested unrolling, NK1304; @unroll(up_to: N). The checker’s and emitter’s machinery for T::fields (facts.unrolled, check_program_turns, walk.specialising, emit_stmt_for) generalised from types to values, not duplicated.comptime parameters.--comptime.continue/break in a turn, a message naming the turn, NK1152 past the budget, NK1304, NK1305, both copies of a comptime? function, a decided match, a computed result type.Then #673 step 7 builds on it. The commit that builds the last step says Fixes #906.
Owner, 2026-10-28: Q1-Q4 decided as recommended - comptime for over a build-time value; an if on a build-time condition decided while building, without a word; per-turn checking and messages as ADR-304 D7-D8; each turn counts against ADR-321’s budget (NK1152). Q5 (how a build-time value reaches a method) is open: the options need to be laid out first. The measurement (unrolled if chain against a table loop) is still owed; whether code can be slower than a table is being explained to the owner.
Generated by Claude Code
Probe for step 1 (tools lane, j3 report 2026-10-31): a comptime value parameter does not parse at all today.
fn twice(comptime n: i64) -> i64 {
return n * 2
}
fn main() {
println(f"{twice(3)}")
}
Today: “comptime is a reserved word, so it can’t be used as a name here” at the parameter. Part I (Decimal[comptime precision: i64 …], get(self, comptime path: String, …)) and Part II 10.3 (comptime f: meta::Field means the same as f: meta::Field) write it. The tools lane does not need it for #1019 now (a meta::Field parameter is comptime by its type); the reflected-field build-time evaluation is #1087.
Generated by Claude Code