fieldtest: raw-buf milestone — 4 examples, 3 findings (refs #7)

Milestone-close fieldtest for the raw-buf milestone, milestone-scope
variant: four end-to-end scenarios derived top-down from the milestone
promise (construct via (new RawBuf <elem> <size>), fill/read via
set/get, size-only buffers, element variety across {Int,Float,Bool},
forbidden-element reject at check, buffer threading under own/borrow).

Result confirms the milestone-promise hypothesis — RawBuf is clean
end to end, zero bugs:
- mrb_1 Int fill/read loop: check ok, run + native build both print 70
- mrb_2 Float own->own threading + borrow read: prints 3.5
- mrb_3 size-only Bool buffer (#51 legitimate-but-unobserved case): prints 8
- mrb_4 Unit element: rejected at check with a precise
  param-not-in-restricted-set diagnostic; build stops at the same
  error, codegen never reached (the #51 fix)

Two [working] findings (carry-on) and one [spec_gap]: the
kernel-extensions whitepaper (design/models/0007) teaches bare-mode
fn-type slots that the post-#55 parser rejects. Verified and triaged
separately; the ledger fix follows in its own commit.
This commit is contained in:
2026-06-02 10:46:16 +02:00
parent 2ca483dbfd
commit 9545257333
5 changed files with 210 additions and 0 deletions
+29
View File
@@ -0,0 +1,29 @@
(module mrb_1_histogram
(fn fill
(doc "Fill an Int RawBuf at indices i..n with the running value v, stepping v by 7 each slot. own->own threading: the buffer is consumed and returned per RawBuf.set, so the recursion re-binds buf each step.")
(type (fn-type
(params (own (con RawBuf (con Int))) (own (con Int)) (own (con Int)) (own (con Int)))
(ret (own (con RawBuf (con Int))))))
(params buf i n v)
(body
(if (app eq i n)
buf
(tail-app fill (app RawBuf.set buf i v) (app + i 1) n (app + v 7)))))
(fn sum
(doc "Read back indices i..n of a borrow-mode RawBuf and total them. Reader: receiver is borrowed, never consumed.")
(type (fn-type
(params (borrow (con RawBuf (con Int))) (own (con Int)) (own (con Int)) (own (con Int)))
(ret (own (con Int)))))
(params buf i n acc)
(body
(if (app eq i n)
acc
(tail-app sum buf (app + i 1) n (app + acc (app RawBuf.get buf i))))))
(fn main
(doc "Allocate a 5-slot Int RawBuf, fill it (0,7,14,21,28), then sum it back and print 70.")
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
(params)
(body
(let buf (new RawBuf (con Int) 5)
(let buf (app fill buf 0 5 0)
(app print (app sum buf 0 5 0)))))))
+26
View File
@@ -0,0 +1,26 @@
(module mrb_2_float_smooth
(fn store_pair
(doc "Thread a Float RawBuf through an own->own helper that writes two slots and hands the buffer back. Tests threading a buffer through a function under the uniqueness/mode discipline: caller gives up own, callee returns own.")
(type (fn-type
(params (own (con RawBuf (con Float))) (own (con Float)) (own (con Float)))
(ret (own (con RawBuf (con Float))))))
(params buf a b)
(body
(let buf (app RawBuf.set buf 0 a)
(app RawBuf.set buf 1 b))))
(fn average
(doc "Read both slots through a borrow and return their mean. Float element variety: double load + float arithmetic.")
(type (fn-type
(params (borrow (con RawBuf (con Float))))
(ret (own (con Float)))))
(params buf)
(body
(app / (app + (app RawBuf.get buf 0) (app RawBuf.get buf 1)) 2.0)))
(fn main
(doc "Allocate a 2-slot Float RawBuf, store 3.0 and 4.0 via the own->own helper, then print their average (3.5).")
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
(params)
(body
(let buf (new RawBuf (con Float) 2)
(let buf (app store_pair buf 3.0 4.0)
(app print (app average buf)))))))
@@ -0,0 +1,15 @@
(module mrb_3_bool_capacity
(fn capacity
(doc "Read the size of a borrow-mode Bool RawBuf without ever touching get/set. The #51 legitimate-but-unobserved case: an explicit Bool element type is named at construction, but only .size is ever used.")
(type (fn-type
(params (borrow (con RawBuf (con Bool))))
(ret (own (con Int)))))
(params buf)
(body (app RawBuf.size buf)))
(fn main
(doc "Allocate an 8-slot Bool RawBuf and print its capacity (8) via RawBuf.size only — never get/set. Exercises a size-only Bool buffer.")
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
(params)
(body
(let buf (new RawBuf (con Bool) 8)
(app print (app capacity buf))))))
@@ -0,0 +1,8 @@
(module mrb_4_unit_element_reject
(fn main
(doc "An LLM author mistakenly names Unit as the element type of a RawBuf. Unit is not in RawBuf's permitted element set {Int, Float, Bool}, so this must be rejected at `ail check` with a param-in diagnostic naming Unit — NOT crash later at build/codegen (the #51 fix). The buffer is only sized and its size printed, so the error is purely the forbidden element type.")
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
(params)
(body
(let buf (new RawBuf (con Unit) 4)
(app print (app RawBuf.size buf))))))