Files
AILang/examples/fieldtest/rbx_1_float_window_stats.ail
T
Brummel 1b2d23ec42 fieldtest: raw-buf comprehensive — 4 examples, 8 findings (refs #7)
Comprehensive usability re-test of the RawBuf kernel extension in
natural LLM-author decompositions the prior field test (0058) did not
exercise: a Float RawBuf in a user ADT read through two borrow helpers,
a Bool flag buffer filled with a computed value, an Int fib buffer whose
fill reads its own writes plus two composed borrow summaries, and a
forbidden core-primitive element. All three working fixtures build, run
to expected values, and report live=0 across Float/Bool/Int widths —
the core RawBuf surface (borrow-helper composition, fill loops,
RawBuf-in-ADT, element widths) genuinely holds together.

Orchestrator triage corrected the fieldtester's run, which executed a
stale target/release/ail (built before the #50 fix). Every outcome was
re-verified against a fresh build:

- F2 (bare RawBuf ADT field unresolved) — RETRACTED: a stale-binary
  false positive. On a fresh build the bare name resolves in every
  configuration (ctor name == or != type name; builds/runs live=0). The
  #50 fix is correct and general.
- F7 (NEW, issue #51) — a `check`-clean program crashes `build`: a
  buffer whose element type is never observed by a later get/set
  defaults its element to Unit in monomorphisation and hits an
  unregistered `RawBuf_new__Unit` intercept. Affects a legitimate
  `RawBuf<Int>` used only for its size AND a forbidden locally-
  constructed element. Root: the `(new T ...)` desugar drops the
  explicit element annotation; honouring it reverses the milestone's
  § Term::New desugar decision, so it routes through brainstorm.
- F8 (process) — the field test ran stale; the fieldtester agent now
  builds from the current tree before running (plugin fix).

F1 (spec_gap) resolved here: the design ledger's §Series substrate ctor
wrote the storage field `(own (RawBuf a))`, which does not parse (`own`
is fn-param/ret only). Rewritten to the verified-authorable `(con RawBuf
a)`. The rest of the §Series listing is illustrative and its element-
less `(new RawBuf lookback)` construction is entangled with #51; a full
compile-verification of that listing belongs with the Series-substrate
work.

F5 (param-in rejects a forbidden core primitive, message names the set)
and F4/F3 (borrow composition; substrate composite) carry on. F6
(param-in set rendered as a Rust-debug list) filed as #52.

refs #7
2026-05-30 18:29:00 +02:00

93 lines
3.8 KiB
Plaintext

; Fieldtest raw-buf comprehensive .1 (Axes 1+2+3+4 combined — the
; "Series substrate" shape with a Float element width).
;
; Task an LLM author is naturally given: "model a fixed-size window of
; Float samples with a running total, fill it from a loop, then report
; the window mean and the window maximum through read-only helpers."
;
; The natural decomposition wraps a RawBuf<Float> together with a
; bookkeeping `count` field in a user ADT (Window), exactly the Series
; substrate the ledger (design/models/0007 §Series) describes — an ADT
; holding `(own (RawBuf a))` plus Int bookkeeping. The buffer is filled
; via a (loop ...)/recur (runtime-N, not literal indices), and the
; read-back is factored into two `borrow (Window)` helpers (`mean`,
; `wmax`) that each pattern-match the ADT and drive a read loop off the
; bookkeeping count, reading the buffer through `RawBuf.get` on a borrow.
;
; This stresses, in one program:
; - Float element width through a fill loop (not just literal sets).
; - A RawBuf stored in a user ADT field (the #50 substrate shape).
; - TWO borrow-receiver helpers composing over the same wrapped buffer
; (the #46 borrow-receiver-read fix, under composition + behind a
; match on the ADT).
; - The drop cascade: the Window ADT owns the buffer; dropping the
; Window frees the slab. Leak-clean expected under AILANG_RC_STATS.
;
; Window of 4 samples: 2.0, 4.0, 6.0, 8.0.
; mean = 20.0 / 4 = 5.0
; wmax = 8.0
; Expected stdout: two lines, "5.0" then "8.0".
(module rbx_1_float_window_stats
; NOTE (field test): the ledger's §Series substrate form writes the
; storage field as `(own (RawBuf a))`. That does NOT parse here — `own`
; in a ctor field position is rejected (surface-parse-error). And the
; bare `(con RawBuf (con Float))` field gives a type-mismatch
; (expected RawBuf<Float>, got raw_buf.RawBuf<Float>). The only form
; that checks is the fully-qualified `raw_buf.RawBuf`. See findings.
(data Window
(ctor W (con raw_buf.RawBuf (con Float)) (con Int)))
(fn build_window
(doc "Allocate a 4-slot Float buffer, fill slot i with (2*(i+1)), wrap in a Window with count=4.")
(type (fn-type (params (con Int)) (ret (own (con Window)))))
(params n)
(body
(let buf (new RawBuf (con Float) 4)
(let filled
(loop (b (con RawBuf (con Float)) buf) (i (con Int) 0)
(if (app ge i n)
b
(recur (app RawBuf.set b i (app int_to_float (app * 2 (app + i 1))))
(app + i 1))))
(term-ctor Window W filled n)))))
(fn mean
(doc "Average of the first count slots, read through a borrow of the Window.")
(type (fn-type (params (borrow (con Window))) (ret (con Float))))
(params w)
(body
(match w
(case (pat-ctor W buf count)
(app /
(loop (acc (con Float) 0.0) (i (con Int) 0)
(if (app ge i count)
acc
(recur (app + acc (app RawBuf.get buf i))
(app + i 1))))
(app int_to_float count))))))
(fn wmax
(doc "Maximum of the first count slots, read through a borrow of the Window.")
(type (fn-type (params (borrow (con Window))) (ret (con Float))))
(params w)
(body
(match w
(case (pat-ctor W buf count)
(loop (mx (con Float) 0.0) (i (con Int) 0)
(if (app ge i count)
mx
(recur (if (app float_gt (app RawBuf.get buf i) mx)
(app RawBuf.get buf i)
mx)
(app + i 1))))))))
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body
(let w (app build_window 4)
(seq (seq (app print (app mean w)) (do io/print_str "\n"))
(seq (app print (app wmax w)) (do io/print_str "\n")))))))