feat(lang): eliminate the Implicit ownership default — totality + the drop-soundness it demasks (#55)
Deletes `ParamMode::Implicit`. `ParamMode` is now `{Own, Borrow}`:
every fn-type slot on every signature carries an explicit `own` or
`borrow`, no defaulted position survives anywhere (model 0008 §2,
spec 0062). The parser rejects a bare fn-type slot; `borrow-return`
and `borrow-over-value` reject at the signature; the corpus is
migrated to minimal-ownership modes (consumed ⇒ own, read-only-heap
⇒ borrow, value ⇒ trivial-own). The documented `Implicit`-ret-mode
leak is fixed: an owned heap return now drops exactly once (live=0,
acceptance criterion 5).
This was the easy half. Removing the default ACTIVATED a family of
drop paths that `Implicit` had silently skipped — the pre-cutover
language was leaking (and in places mis-dropping) here rather than
crashing, because an Implicit scrutinee turned the drop off. Making
the modes explicit (Own) turned those paths on and exposed two
latent-bug clusters, all fixed RED-first as part of this cutover:
Drop-soundness family (four legs):
A. lit-sub-pattern double-free — the desugar re-matched the same
owned scrutinee in the lit fall-through; fixed by grouping
consecutive same-ctor arms into one match (bind fields once),
in ailang-core desugar.
B. Cons-husk leak on non-tail arm bodies — the lit-sub-pattern
desugar rebound the owned scrutinee via `Let $mp = xs`, which
bumped consume_count and suppressed the existing fn-return
partial_drop. Fixed by not rebinding a bare-Var scrutinee
(one husk-freeing mechanism, not two).
C. polymorphic `drop_<T>` rc_dec'd monomorphised value fields —
the per-ADT drop fn was emitted once from the polymorphic
TypeDef, defaulting type-var fields to ptr and rc_dec'ing
inline Ints (segfault). Fixed with per-monomorph drop
functions (new ailang-codegen::dropmono): the drop set is
collected from the lowered MIR, value-type fields are skipped,
heap fields still freed once; monomorphic-concrete ADTs keep
their byte-identical un-suffixed drop symbol.
D. static Str literal passed to an `(own Str)` param — the
literal lowers to a header-less rodata constant; the callee's
now-active rc_dec read its length field as a refcount and
freed a static address (segfault). Fixed with the missing
fourth StrRep::Static→Heap promotion in lower_to_mir's App arm,
gated on Own mode (borrow args stay static, no regression).
over-strict-mode lint over-fired: it suggested `(borrow V)` for
value-typed params (which `borrow-over-value` rejects — own is the
only legal mode there) and fired on `(intrinsic)` bodies (whose
consumption the linearity walk cannot observe). Tightened to skip
both; contract 0008 updated to the narrowed firing scope.
Irreversible step — canonical-form hash reset (model 0008 §6,
acceptance criterion 6). Every signature now carries explicit modes,
so the hashable canonical JSON changed for every module. RATIFY:
the corpus-wide hash-pin reset (hash_pin, prelude_module_hash_pin,
mono_hash_stability, eq_ord_e2e, embed_export_hash_stable, the
ct4/iter*/loop_recur schema-extension pins) and the list ir_snapshot
golden were regenerated once, deliberately, as the intended one-time
consequence of removing the mode elision from the canonical form —
not a regression. Each regenerated hash verified deterministic across
two runs.
Also fixes a pre-existing latent failure surfaced by the verification
gate, unrelated to this cutover: the `every_contract_names_a_resolvable_
ratifying_test` resolver (design_index_pin) could not resolve the
" + " dual-link ratifying-test form (`uniqueness.rs + linearity.rs`)
that the #57 audit-close (dfdc65f) introduced — it shipped red on that
commit. Resolver taught the dual-link form, mirroring its sibling.
Verification: cargo test --workspace = 731 passed, 0 failed (twice,
stable); e2e 102 passed, no binary exits non-zero (corpus crash-free);
grep-clean for Implicit/fn_implicit/mode_eq across crates; every drop
fix confirmed via emitted IR + AILANG_RC_STATS balance on the head==K,
head!=K, and Nil paths. Three BLOCKEDs en route (the unsound first
husk-dec attempt, the over-strict derivation premise, the leg-B fix
direction) were each treated as a real design/spec gap and rediagnosed,
not patched over.
Supersedes #54 (return-position-only leak patch). Precondition #57
(linearity hardening) was already met. Spec docs/specs/0062, plan
docs/plans/0121.
closes #55
This commit is contained in:
@@ -9,8 +9,8 @@
|
||||
(export "ema_step")
|
||||
(type
|
||||
(fn-type
|
||||
(params (con Int) (con Int))
|
||||
(ret (con Int))))
|
||||
(params (own (con Int)) (own (con Int)))
|
||||
(ret (own (con Int)))))
|
||||
(params state sample)
|
||||
(body
|
||||
(app + state
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
(export "leaky_step")
|
||||
(type
|
||||
(fn-type
|
||||
(params (con Float) (con Float))
|
||||
(ret (con Float))))
|
||||
(params (own (con Float)) (own (con Float)))
|
||||
(ret (own (con Float)))))
|
||||
(params state sample)
|
||||
(body
|
||||
(app + (app * state 0.5) sample))))
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
(type
|
||||
(fn-type
|
||||
(params (own (con IntList)))
|
||||
(ret (con Int))))
|
||||
(ret (own (con Int)))))
|
||||
(params xs)
|
||||
(body
|
||||
(match xs
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
(export "tick")
|
||||
(type
|
||||
(fn-type
|
||||
(params (con Int))
|
||||
(ret (con Int))
|
||||
(params (own (con Int)))
|
||||
(ret (own (con Int)))
|
||||
(effects IO)))
|
||||
(params n)
|
||||
(body
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
(doc "Return the FizzBuzz label for n, or the empty string if n is a plain number.")
|
||||
(type
|
||||
(fn-type
|
||||
(params (con Int))
|
||||
(ret (con Str))))
|
||||
(params (own (con Int)))
|
||||
(ret (own (con Str)))))
|
||||
(params n)
|
||||
(body
|
||||
(if (app eq (app % n 15) 0)
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
(fn emit_one
|
||||
(doc "Print the FizzBuzz label or the number itself.")
|
||||
(type (fn-type (params (con Int)) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params (own (con Int))) (ret (own (con Unit))) (effects IO)))
|
||||
(params n)
|
||||
(body
|
||||
(let label (app classify n)
|
||||
@@ -58,7 +58,7 @@
|
||||
|
||||
(fn loop
|
||||
(doc "Tail-recursive driver over [i..stop].")
|
||||
(type (fn-type (params (con Int) (con Int)) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params (own (con Int)) (own (con Int))) (ret (own (con Unit))) (effects IO)))
|
||||
(params i stop)
|
||||
(body
|
||||
(if (app gt i stop)
|
||||
@@ -68,6 +68,6 @@
|
||||
(tail-app loop (app + i 1) stop)))))
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body (app loop 1 15))))
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
(app eq (app * a d) (app * b c)))))))))))
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(let r_1_2 (term-ctor Rational MkRational 1 2)
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
(fn fabs
|
||||
(doc "Float absolute value via the named-fn comparison surface.")
|
||||
(type (fn-type (params (con Float)) (ret (con Float))))
|
||||
(type (fn-type (params (own (con Float))) (ret (own (con Float)))))
|
||||
(params x)
|
||||
(body
|
||||
(if (app float_lt x 0.0)
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
(fn iterate
|
||||
(doc "Tail-recursive Newton iteration. Stops when |xnew - x| < tol.")
|
||||
(type (fn-type (params (con Float) (con Float) (con Float)) (ret (con Float))))
|
||||
(type (fn-type (params (own (con Float)) (own (con Float)) (own (con Float))) (ret (own (con Float)))))
|
||||
(params n x tol)
|
||||
(body
|
||||
(let xnew (app / (app + x (app / n x)) 2.0)
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
(fn sqrt
|
||||
(doc "sqrt n via Newton with initial guess 1.0 and tolerance 1e-10. Returns 0.0 for n == 0.0; assumes n >= 0.")
|
||||
(type (fn-type (params (con Float)) (ret (con Float))))
|
||||
(type (fn-type (params (own (con Float))) (ret (own (con Float)))))
|
||||
(params n)
|
||||
(body
|
||||
(if (app float_eq n 0.0)
|
||||
@@ -52,7 +52,7 @@
|
||||
(app iterate n 1.0 0.0000000001))))
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(seq (app print (app sqrt 4.0))
|
||||
|
||||
@@ -18,6 +18,6 @@
|
||||
|
||||
(module eqord_4_float_ord_must_fail
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body (app print (if (app lt 1.5 2.5) 1 0)))))
|
||||
|
||||
@@ -11,6 +11,6 @@
|
||||
|
||||
(module eqord_5_float_eq_must_fail
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body (app print (if (app eq 1.5 1.5) 1 0)))))
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
(doc "Recurse k times applying x' = 0.5 * (x + n/x).")
|
||||
(type
|
||||
(fn-type
|
||||
(params (con Float) (con Float) (con Int))
|
||||
(ret (con Float))))
|
||||
(params (own (con Float)) (own (con Float)) (own (con Int)))
|
||||
(ret (own (con Float)))))
|
||||
(params n x k)
|
||||
(body
|
||||
(if (app eq k 0)
|
||||
@@ -27,12 +27,12 @@
|
||||
|
||||
(fn sqrt
|
||||
(doc "20-step Newton iteration starting from x0 = n.")
|
||||
(type (fn-type (params (con Float)) (ret (con Float))))
|
||||
(type (fn-type (params (own (con Float))) (ret (own (con Float)))))
|
||||
(params n)
|
||||
(body (app newton_iter n n 20)))
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(app print (app sqrt 2.0)))))
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
(doc "Tail-recursive sum with accumulator.")
|
||||
(type
|
||||
(fn-type
|
||||
(params (con IntList) (con Int))
|
||||
(ret (con Int))))
|
||||
(params (borrow (con IntList)) (own (con Int)))
|
||||
(ret (own (con Int)))))
|
||||
(params xs acc)
|
||||
(body
|
||||
(match xs
|
||||
@@ -35,8 +35,8 @@
|
||||
(doc "Tail-recursive length with accumulator.")
|
||||
(type
|
||||
(fn-type
|
||||
(params (con IntList) (con Int))
|
||||
(ret (con Int))))
|
||||
(params (borrow (con IntList)) (own (con Int)))
|
||||
(ret (own (con Int)))))
|
||||
(params xs acc)
|
||||
(body
|
||||
(match xs
|
||||
@@ -46,7 +46,7 @@
|
||||
|
||||
(fn mean
|
||||
(doc "Mean as Float = sum / count, both promoted via int_to_float.")
|
||||
(type (fn-type (params (con IntList)) (ret (con Float))))
|
||||
(type (fn-type (params (borrow (con IntList))) (ret (own (con Float)))))
|
||||
(params xs)
|
||||
(body
|
||||
(app /
|
||||
@@ -54,7 +54,7 @@
|
||||
(app int_to_float (app count_acc xs 0)))))
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(app print
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
(fn classify
|
||||
(doc "-1=NaN, 0=infinite, 1=finite. Uses is_nan + abs > huge.")
|
||||
(type (fn-type (params (con Float)) (ret (con Int))))
|
||||
(type (fn-type (params (own (con Float))) (ret (own (con Int)))))
|
||||
(params x)
|
||||
(body
|
||||
(if (app is_nan x)
|
||||
@@ -44,7 +44,7 @@
|
||||
1)))))
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(seq (app print (app / 6.0 3.0))
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
(module floats_4_float_to_str_reach
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(do io/print_str (app float_to_str 3.14)))))
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
(doc "Tail-recursive factorial accumulator: fact_acc(n, acc) = n!*acc.")
|
||||
(type
|
||||
(fn-type
|
||||
(params (con Int) (con Int))
|
||||
(ret (con Int))))
|
||||
(params (own (con Int)) (own (con Int)))
|
||||
(ret (own (con Int)))))
|
||||
(params n acc)
|
||||
(body
|
||||
(if (app eq n 0)
|
||||
@@ -16,13 +16,13 @@
|
||||
(doc "Factorial of a non-negative Int.")
|
||||
(type
|
||||
(fn-type
|
||||
(params (con Int))
|
||||
(ret (con Int))))
|
||||
(params (own (con Int)))
|
||||
(ret (own (con Int)))))
|
||||
(params n)
|
||||
(body (app fact_acc n 1)))
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(seq
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
(case (pat-ctor Blue) "Blue")))))))
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(seq
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
(doc "A user-defined typeclass: produce a short Str describing a value.")
|
||||
(param a)
|
||||
(method describe
|
||||
(type (fn-type (params (borrow a)) (ret (con Str))))))
|
||||
(type (fn-type (params (borrow a)) (ret (own (con Str)))))))
|
||||
|
||||
(data Shape
|
||||
(ctor Circle (con Int))
|
||||
@@ -42,13 +42,13 @@
|
||||
(constraints (constraint Describe a))
|
||||
(fn-type
|
||||
(params (borrow a))
|
||||
(ret (con Unit))
|
||||
(ret (own (con Unit)))
|
||||
(effects IO))))
|
||||
(params x)
|
||||
(body (do io/print_str (app describe x))))
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(seq
|
||||
|
||||
@@ -2,19 +2,19 @@
|
||||
|
||||
(fn square
|
||||
(doc "Multiply an Int by itself.")
|
||||
(type (fn-type (params (con Int)) (ret (con Int))))
|
||||
(type (fn-type (params (own (con Int))) (ret (own (con Int)))))
|
||||
(params x)
|
||||
(body (app * x x)))
|
||||
|
||||
(fn cube
|
||||
(doc "Raise an Int to the third power.")
|
||||
(type (fn-type (params (con Int)) (ret (con Int))))
|
||||
(type (fn-type (params (own (con Int))) (ret (own (con Int)))))
|
||||
(params x)
|
||||
(body (app * x (app square x))))
|
||||
|
||||
(fn abs_int
|
||||
(doc "Absolute value of an Int.")
|
||||
(type (fn-type (params (con Int)) (ret (con Int))))
|
||||
(type (fn-type (params (own (con Int))) (ret (own (con Int)))))
|
||||
(params x)
|
||||
(body
|
||||
(if (app lt x 0)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
(import forma_4_intmath_lib)
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(seq
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
|
||||
(fn add
|
||||
(doc "Plain Int addition. Used as the (b, a) -> b arg to List.fold_left.")
|
||||
(type (fn-type (params (con Int) (con Int)) (ret (con Int))))
|
||||
(type (fn-type (params (own (con Int)) (own (con Int))) (ret (own (con Int)))))
|
||||
(params acc x)
|
||||
(body (app + acc x)))
|
||||
|
||||
(fn main
|
||||
(doc "Build a List<Int> of [1,2,3,4,5], print its length (5), then its sum (15).")
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(let xs
|
||||
|
||||
@@ -20,12 +20,12 @@
|
||||
|
||||
(fn new
|
||||
(doc "Build a Counter initialised to the given value.")
|
||||
(type (fn-type (params (con Int)) (ret (con Counter))))
|
||||
(type (fn-type (params (own (con Int))) (ret (own (con Counter)))))
|
||||
(params n)
|
||||
(body (term-ctor Counter MkCounter n)))
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(let c (new Counter 42)
|
||||
|
||||
@@ -10,12 +10,12 @@
|
||||
(ctor MkCounter (con Int)))
|
||||
|
||||
(fn value
|
||||
(type (fn-type (params (con Counter)) (ret (con Int))))
|
||||
(type (fn-type (params (borrow (con Counter))) (ret (own (con Int)))))
|
||||
(params c)
|
||||
(body (match c (case (pat-ctor MkCounter x) x))))
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(let c (term-ctor Counter MkCounter 41)
|
||||
|
||||
@@ -17,12 +17,12 @@
|
||||
|
||||
(fn unwrap
|
||||
(doc "Project the contained Int out of a NumBox<Int>.")
|
||||
(type (fn-type (params (con NumBox (con Int))) (ret (con Int))))
|
||||
(type (fn-type (params (own (con NumBox (con Int)))) (ret (own (con Int)))))
|
||||
(params b)
|
||||
(body (match b (case (pat-ctor MkNumBox x) x))))
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(let b (term-ctor NumBox MkNumBox 17)
|
||||
|
||||
@@ -13,11 +13,11 @@
|
||||
|
||||
(fn unwrap_str
|
||||
(doc "BAD: NumBox is restricted to {Int, Float}, but we ask for Str. Expected: ParamNotInRestrictedSet on the type signature.")
|
||||
(type (fn-type (params (con NumBox (con Str))) (ret (con Str))))
|
||||
(type (fn-type (params (own (con NumBox (con Str)))) (ret (own (con Str)))))
|
||||
(params b)
|
||||
(body (match b (case (pat-ctor MkNumBox x) x))))
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body (do io/print_str ""))))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
(module loop_recur_1_isqrt_newton
|
||||
(fn main
|
||||
(doc "Integer square root of 152399025 (= 12345^2) via Newton's method, then a sanity-difference. Expected stdout: 12345 then 0.")
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(let r (app isqrt 152399025)
|
||||
@@ -9,7 +9,7 @@
|
||||
(app print (app - r 12345))))))
|
||||
(fn isqrt
|
||||
(doc "Newton's method for floor(sqrt(n)). Two binders: x (current guess) and prev (previous guess, to detect the fixpoint/2-cycle). The recur is buried inside a nested if, not at body toplevel.")
|
||||
(type (fn-type (params (con Int)) (ret (con Int))))
|
||||
(type (fn-type (params (own (con Int))) (ret (own (con Int)))))
|
||||
(params n)
|
||||
(body
|
||||
(if (app lt n 2)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
(module loop_recur_2_collatz
|
||||
(fn main
|
||||
(doc "Collatz step counts. collatz_len(27)=111, collatz_len(97)=118, collatz_len(1)=0. Expected stdout (per line): 111, 118, 0.")
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(seq (app print (app collatz_len 27))
|
||||
@@ -9,7 +9,7 @@
|
||||
(app print (app collatz_len 1))))))
|
||||
(fn collatz_len
|
||||
(doc "Number of Collatz steps to reach 1. Two binders: n (current value) and steps (accumulator). Parity dispatch is a `match` on n%2; the recur lives in the tail of each match arm, not at body toplevel.")
|
||||
(type (fn-type (params (con Int)) (ret (con Int))))
|
||||
(type (fn-type (params (own (con Int))) (ret (own (con Int)))))
|
||||
(params start)
|
||||
(body
|
||||
(loop (n (con Int) start) (steps (con Int) 0)
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
; Expected: `ail check` exits 1 with code recur-outside-loop.
|
||||
(module loop_recur_3a_recur_outside_loop
|
||||
(fn countdown
|
||||
(type (fn-type (params (con Int)) (ret (con Int))))
|
||||
(type (fn-type (params (own (con Int))) (ret (own (con Int)))))
|
||||
(params n)
|
||||
(body
|
||||
(if (app eq n 0)
|
||||
0
|
||||
(recur (app - n 1)))))
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body (app print (app countdown 5)))))
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
; Expected: `ail check` exits 1 with code recur-arity-mismatch.
|
||||
(module loop_recur_3b_recur_arity
|
||||
(fn sum_to
|
||||
(type (fn-type (params (con Int)) (ret (con Int))))
|
||||
(type (fn-type (params (own (con Int))) (ret (own (con Int)))))
|
||||
(params n)
|
||||
(body
|
||||
(loop (acc (con Int) 0) (i (con Int) 1)
|
||||
@@ -12,6 +12,6 @@
|
||||
acc
|
||||
(recur (app + acc i))))))
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body (app print (app sum_to 10)))))
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
; Expected: `ail check` exits 1 with code recur-type-mismatch.
|
||||
(module loop_recur_3c_recur_type
|
||||
(fn count_down
|
||||
(type (fn-type (params (con Int)) (ret (con Int))))
|
||||
(type (fn-type (params (own (con Int))) (ret (own (con Int)))))
|
||||
(params start)
|
||||
(body
|
||||
(loop (i (con Int) start)
|
||||
@@ -12,6 +12,6 @@
|
||||
i
|
||||
(recur (app gt i 0))))))
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body (app print (app count_down 5)))))
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
; Expected: `ail check` exits 1 with code recur-not-in-tail-position.
|
||||
(module loop_recur_3d_recur_not_tail
|
||||
(fn factorial
|
||||
(type (fn-type (params (con Int)) (ret (con Int))))
|
||||
(type (fn-type (params (own (con Int))) (ret (own (con Int)))))
|
||||
(params n)
|
||||
(body
|
||||
(loop (i (con Int) n)
|
||||
@@ -13,6 +13,6 @@
|
||||
1
|
||||
(app * i (recur (app - i 1)))))))
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body (app print (app factorial 5)))))
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
; Expected: `ail check` exits 1 with code loop-binder-captured-by-lambda.
|
||||
(module loop_recur_3e_binder_captured
|
||||
(fn apply_int
|
||||
(type (fn-type (params (fn-type (params (con Int)) (ret (con Int))) (con Int)) (ret (con Int))))
|
||||
(type (fn-type (params (own (fn-type (params (own (con Int))) (ret (own (con Int))))) (own (con Int))) (ret (own (con Int)))))
|
||||
(params f x)
|
||||
(body (app f x)))
|
||||
(fn sum_to
|
||||
(type (fn-type (params (con Int)) (ret (con Int))))
|
||||
(type (fn-type (params (own (con Int))) (ret (own (con Int)))))
|
||||
(params n)
|
||||
(body
|
||||
(loop (acc (con Int) 0) (i (con Int) 1)
|
||||
@@ -18,6 +18,6 @@
|
||||
(recur (app apply_int (lam (params (typed d (con Int))) (ret (con Int)) (body (app + acc d))) i)
|
||||
(app + i 1))))))
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body (app print (app sum_to 10)))))
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
(module loop_recur_4_gcd_value_pos
|
||||
(fn gcd
|
||||
(doc "Euclidean gcd via loop/recur. Two binders a,b; recur in the tail of the else branch.")
|
||||
(type (fn-type (params (con Int) (con Int)) (ret (con Int))))
|
||||
(type (fn-type (params (own (con Int)) (own (con Int))) (ret (own (con Int)))))
|
||||
(params x y)
|
||||
(body
|
||||
(loop (a (con Int) x) (b (con Int) y)
|
||||
@@ -18,7 +18,7 @@
|
||||
a
|
||||
(recur b (app % a b))))))
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(app print (app + (app gcd 48 18) (app gcd 1071 462))))))
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
(module loop_recur_5_event_loop_noterm
|
||||
(fn run_forever
|
||||
(doc "Infinite event loop. Two binders: tick counter and a running parity flag. No branch ever exits via a non-recur term.")
|
||||
(type (fn-type (params) (ret (con Int))))
|
||||
(type (fn-type (params) (ret (own (con Int)))))
|
||||
(params)
|
||||
(body
|
||||
(loop (tick (con Int) 0) (parity (con Int) 0)
|
||||
@@ -14,6 +14,6 @@
|
||||
(recur (app + tick 1) 1)
|
||||
(recur (app + tick 1) 0)))))
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body (app print (app run_forever)))))
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
(module loop_recur_5b_event_loop_noterm
|
||||
(fn run_forever
|
||||
(doc "Infinite event loop. Two binders: tick counter and a running parity flag. No branch ever exits via a non-recur term.")
|
||||
(type (fn-type (params (con Int)) (ret (con Int))))
|
||||
(type (fn-type (params (own (con Int))) (ret (own (con Int)))))
|
||||
(params start)
|
||||
(body
|
||||
(loop (tick (con Int) start) (parity (con Int) 0)
|
||||
@@ -16,6 +16,6 @@
|
||||
(recur (app + tick 1) 1)
|
||||
(recur (app + tick 1) 0)))))
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body (app print (app run_forever 0)))))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
(module mut-local_1_factorial
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(app print (let prod 1 (let prod (app * prod 1) (let prod (app * prod 2) (let prod (app * prod 3) (let prod (app * prod 4) (let prod (app * prod 5) prod))))))))))
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
|
||||
(fn classify
|
||||
(doc "Return category code 0..3 for temperature t in degrees C.")
|
||||
(type (fn-type (params (con Int)) (ret (con Int))))
|
||||
(type (fn-type (params (own (con Int))) (ret (own (con Int)))))
|
||||
(params t)
|
||||
(body (let code 0 (let code (if (app lt t 0) 0 (if (app lt t 15) 1 (if (app lt t 28) 2 3))) code))))
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(app print (app classify 22)))))
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
(module mut-local_3_horner
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(app print (let acc 2.0 (let acc (app - (app * acc 2.5) 3.0) (let acc (app + (app * acc 2.5) 5.0) (let acc (app - (app * acc 2.5) 7.0) acc))))))))
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
(module mut-local_4_has_small_factor
|
||||
|
||||
(fn has_small_factor
|
||||
(type (fn-type (params (con Int)) (ret (con Bool))))
|
||||
(type (fn-type (params (own (con Int))) (ret (own (con Bool)))))
|
||||
(params n)
|
||||
(body (let found false (let found (if (app eq (app % n 2) 0) true found) (let found (if (app eq (app % n 3) 0) true found) (let found (if (app eq (app % n 5) 0) true found) (let found (if (app eq (app % n 7) 0) true found) found)))))))
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(app print (app has_small_factor 91)))))
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
(fn fill
|
||||
(doc "Fill slots 0..n of buf with (i*i + 1). Linear: own in, own out.")
|
||||
(type (fn-type (params (own (con RawBuf (con Int))) (con Int)) (ret (own (con RawBuf (con Int))))))
|
||||
(type (fn-type (params (own (con RawBuf (con Int))) (own (con Int))) (ret (own (con RawBuf (con Int))))))
|
||||
(params buf n)
|
||||
(body
|
||||
(loop (b (con RawBuf (con Int)) buf) (i (con Int) 0)
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
(fn total
|
||||
(doc "Sum every slot of buf, driving the bound off RawBuf.size.")
|
||||
(type (fn-type (params (borrow (con RawBuf (con Int)))) (ret (con Int))))
|
||||
(type (fn-type (params (borrow (con RawBuf (con Int)))) (ret (own (con Int)))))
|
||||
(params buf)
|
||||
(body
|
||||
(loop (acc (con Int) 0) (i (con Int) 0)
|
||||
@@ -49,7 +49,7 @@
|
||||
(app + i 1))))))
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(let buf (new RawBuf (con Int) 5)
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
(module rawbuf_2_running_max
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(let buf (new RawBuf (con Int) 4)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
(module rawbuf_3_sensor_pair
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(let readings (new RawBuf (con Float) 3)
|
||||
|
||||
@@ -30,6 +30,6 @@
|
||||
|
||||
(fn first_price
|
||||
(doc "Read the first Tick out of a batch buffer. Should never check: RawBuf cannot hold a user ADT.")
|
||||
(type (fn-type (params (borrow (con RawBuf (con Tick)))) (ret (con Tick))))
|
||||
(type (fn-type (params (borrow (con RawBuf (con Tick)))) (ret (own (con Tick)))))
|
||||
(params batch)
|
||||
(body (app RawBuf.get batch 0))))
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
(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)))))
|
||||
(type (fn-type (params (own (con Int))) (ret (own (con Window)))))
|
||||
(params n)
|
||||
(body
|
||||
(let buf (new RawBuf (con Float) 4)
|
||||
@@ -55,7 +55,7 @@
|
||||
|
||||
(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))))
|
||||
(type (fn-type (params (borrow (con Window))) (ret (own (con Float)))))
|
||||
(params w)
|
||||
(body
|
||||
(match w
|
||||
@@ -70,7 +70,7 @@
|
||||
|
||||
(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))))
|
||||
(type (fn-type (params (borrow (con Window))) (ret (own (con Float)))))
|
||||
(params w)
|
||||
(body
|
||||
(match w
|
||||
@@ -84,7 +84,7 @@
|
||||
(app + i 1))))))))
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(let w (app build_window 4)
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
(fn mark_even
|
||||
(doc "Set slot i to (i is even) for i in 0..n. Linear own->own.")
|
||||
(type (fn-type (params (own (con RawBuf (con Bool))) (con Int)) (ret (own (con RawBuf (con Bool))))))
|
||||
(type (fn-type (params (own (con RawBuf (con Bool))) (own (con Int))) (ret (own (con RawBuf (con Bool))))))
|
||||
(params buf n)
|
||||
(body
|
||||
(loop (b (con RawBuf (con Bool)) buf) (i (con Int) 0)
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
(fn count_set
|
||||
(doc "Count the set flags, reading the Bool buffer through a borrow.")
|
||||
(type (fn-type (params (borrow (con RawBuf (con Bool)))) (ret (con Int))))
|
||||
(type (fn-type (params (borrow (con RawBuf (con Bool)))) (ret (own (con Int)))))
|
||||
(params buf)
|
||||
(body
|
||||
(loop (acc (con Int) 0) (i (con Int) 0)
|
||||
@@ -49,7 +49,7 @@
|
||||
(app + i 1))))))
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(let buf (new RawBuf (con Bool) 6)
|
||||
|
||||
@@ -17,12 +17,12 @@
|
||||
|
||||
(fn make_presence
|
||||
(doc "Try to allocate a RawBuf of Unit — forbidden element type.")
|
||||
(type (fn-type (params (con Int)) (ret (own (con RawBuf (con Unit))))))
|
||||
(type (fn-type (params (own (con Int))) (ret (own (con RawBuf (con Unit))))))
|
||||
(params n)
|
||||
(body (new RawBuf (con Unit) n)))
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(let buf (app make_presence 3)
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
(fn fill
|
||||
(doc "Fill slot i with fib(i) for i in 0..n. Linear own->own.")
|
||||
(type (fn-type (params (own (con RawBuf (con Int))) (con Int)) (ret (own (con RawBuf (con Int))))))
|
||||
(type (fn-type (params (own (con RawBuf (con Int))) (own (con Int))) (ret (own (con RawBuf (con Int))))))
|
||||
(params buf n)
|
||||
(body
|
||||
; Seed slots 0 and 1 to 1, then each later slot = sum of prior two,
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
(fn total
|
||||
(doc "Sum every slot, borrow receiver.")
|
||||
(type (fn-type (params (borrow (con RawBuf (con Int)))) (ret (con Int))))
|
||||
(type (fn-type (params (borrow (con RawBuf (con Int)))) (ret (own (con Int)))))
|
||||
(params buf)
|
||||
(body
|
||||
(loop (acc (con Int) 0) (i (con Int) 0)
|
||||
@@ -56,7 +56,7 @@
|
||||
|
||||
(fn argmax
|
||||
(doc "Index of the largest slot, borrow receiver. Tracks (best_i, best_v).")
|
||||
(type (fn-type (params (borrow (con RawBuf (con Int)))) (ret (con Int))))
|
||||
(type (fn-type (params (borrow (con RawBuf (con Int)))) (ret (own (con Int)))))
|
||||
(params buf)
|
||||
(body
|
||||
(loop (best_i (con Int) 0) (best_v (con Int) (app RawBuf.get buf 0)) (i (con Int) 0)
|
||||
@@ -67,7 +67,7 @@
|
||||
(recur best_i best_v (app + i 1)))))))
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(let buf (new RawBuf (con Int) 6)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
(fn sum_sq
|
||||
(doc "Sum of i*i for i in 1..=n via loop/recur. Two binders: i (counter), acc (running total).")
|
||||
(type (fn-type (params (con Int)) (ret (con Int))))
|
||||
(type (fn-type (params (own (con Int))) (ret (own (con Int)))))
|
||||
(params n)
|
||||
(body
|
||||
(loop (i (con Int) 1) (acc (con Int) 0)
|
||||
@@ -23,7 +23,7 @@
|
||||
(recur (app + i 1) (app + acc (app * i i)))))))
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(app print (app sum_sq 10)))))
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
(fn grade
|
||||
(doc "Letter-grade code (4=A..0=F) from a numeric score, written as the let-threaded equivalent of a mutable cascade.")
|
||||
(type (fn-type (params (con Int)) (ret (con Int))))
|
||||
(type (fn-type (params (own (con Int))) (ret (own (con Int)))))
|
||||
(params score)
|
||||
(body
|
||||
(let g 0
|
||||
@@ -30,7 +30,7 @@
|
||||
g)))))))
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(seq (app print (app grade 95))
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
(fn poly
|
||||
(doc "Horner-form evaluation of 2x^4+3x^3+0x^2+5x+7 as a straight-line let chain (the faithful let/if form of a mutable acc).")
|
||||
(type (fn-type (params (con Int)) (ret (con Int))))
|
||||
(type (fn-type (params (own (con Int))) (ret (own (con Int)))))
|
||||
(params x)
|
||||
(body
|
||||
(let acc 2
|
||||
@@ -29,7 +29,7 @@
|
||||
acc)))))))
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(app print (app poly 2)))))
|
||||
|
||||
@@ -39,8 +39,8 @@
|
||||
(doc "Thread (rest, depth, ok). Each arm updates a subset of state; the unchanged components must be restated in every tail call.")
|
||||
(type
|
||||
(fn-type
|
||||
(params (own (con TokStream)) (con Int) (con Bool))
|
||||
(ret (con Bool))))
|
||||
(params (own (con TokStream)) (own (con Int)) (own (con Bool)))
|
||||
(ret (own (con Bool)))))
|
||||
(params rest depth ok)
|
||||
(body
|
||||
(match rest
|
||||
@@ -58,12 +58,12 @@
|
||||
(tail-app scan more depth ok)))))))
|
||||
|
||||
(fn balanced
|
||||
(type (fn-type (params (own (con TokStream))) (ret (con Bool))))
|
||||
(type (fn-type (params (own (con TokStream))) (ret (own (con Bool)))))
|
||||
(params s)
|
||||
(body (app scan s 0 true)))
|
||||
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(seq
|
||||
|
||||
Reference in New Issue
Block a user