8e9f0f06a6
Downstream field test of the raw-buf surface as a consumer with only the public interface (design ledger + `ail` CLI; no crate source). Four fixtures under examples/fieldtest/, spec at docs/specs/0058-fieldtest-raw-buf.md. Every recorded outcome reproduced independently before commit. Findings (3 bug, 1 spec_gap, 2 working): - B1 [bug] `borrow (RawBuf a)` receiver is unusable. A fn taking `borrow (RawBuf Int)` that calls RawBuf.get/.size on the parameter even once is rejected `consume-while-borrowed` — the diagnostic names the wrong cause (the receiver is not consumed). The ledger advertises get/size as borrow-receiver ops, so the documented use is unreachable from any helper-function decomposition. This blocks Series (#8) — the milestone's own downstream raison d'être — whose at/total_count read through a `borrow (Series a)`. - B2 [bug] An owned RawBuf threaded through a `loop` binder passes check but panics codegen `unknown variable: b` at build. A plain Int loop binder builds fine, so the fault is specific to an owned RawBuf loop binder. Breaks the check↔codegen agreement. - B3 [bug] `param-not-in-restricted-set` omits the allowed set. design/models/0007 §4 promises the diagnostic "names the offending type and the allowed set"; the shipped message names the type, the type-var, and the home type but not `{Int, Float, Bool}`. A downstream author is told what is wrong but not what is right. - B4 [spec_gap] RawBuf.set receiver double-consume is not enforced; two set calls on the same owned buffer silently alias the slab. Not raw-buf-specific (owned Str/ADT behave identically) — a pre-existing linearity-non-enforcement property. Recorded because RawBuf's own→own mutation is the first place a silent alias yields a mutated-in-place surprise. Ratify in the ledger or open a backlog item for full linear enforcement. - W1 [working] `(new …)` sugar + inference-from-use across Int/Float/Bool builds and runs first try (sensor_pair prints 5.0); the Bool i1/i8 packing edge round-trips. The milestone's cleanest win. - W2 [working] param-in reject fires for both Str and a user TypeDef. Net: B1+B2 mean the only RawBuf programs that build today are straight-line owned let-threading with literal indices — the shipped-fixture shape. Helper decomposition (B1) and runtime-length loop fill (B2) both fail. fieldtest does not self-resolve; routing is the orchestrator's call.
41 lines
1.8 KiB
Plaintext
41 lines
1.8 KiB
Plaintext
; Fieldtest raw-buf.2 (Axis 1 + Axis 4, loop-threaded owned RawBuf).
|
|
; Task: "fill a buffer of N slots with a sequence in a loop, then read it
|
|
; back and print the running maximum." This is the LLM-natural way to
|
|
; populate a buffer whose length is a runtime N rather than three literal
|
|
; (RawBuf.set buf <lit> ...) lines: thread the owned buffer through a
|
|
; (loop ...) / recur, one RawBuf.set per iteration.
|
|
;
|
|
; The whole program is inlined into main (no borrow-mode helper, which
|
|
; rawbuf_1_score_table.ail showed is rejected). The fill loop threads the
|
|
; owned `b` through recur; the read loop drives off RawBuf.size.
|
|
;
|
|
; Expected stdout: 16 (slots 1,4,9,16; running max ends at 16).
|
|
;
|
|
; OUTCOME: `ail check` passes ("ok"), but `ail build` FAILS at codegen:
|
|
; Error: module `rawbuf_2_running_max`: def `main`: unknown variable: `b`
|
|
; The owned-RawBuf `loop` binder `b` threaded through `recur` is visible
|
|
; to the checker but not to codegen. A plain Int loop binder named `b`
|
|
; builds fine, so it is specific to threading an owned RawBuf value
|
|
; through a loop binder. The check<->codegen agreement is broken here.
|
|
|
|
(module rawbuf_2_running_max
|
|
(fn main
|
|
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
|
(params)
|
|
(body
|
|
(let buf (new RawBuf (con Int) 4)
|
|
(let filled
|
|
(loop (b (con RawBuf (con Int)) buf) (i (con Int) 0)
|
|
(if (app ge i 4)
|
|
b
|
|
(recur (app RawBuf.set b i (app * (app + i 1) (app + i 1)))
|
|
(app + i 1))))
|
|
(app print
|
|
(loop (mx (con Int) 0) (i (con Int) 0)
|
|
(if (app ge i (app RawBuf.size filled))
|
|
mx
|
|
(recur (if (app gt (app RawBuf.get filled i) mx)
|
|
(app RawBuf.get filled i)
|
|
mx)
|
|
(app + i 1))))))))))
|