72e54f4fd3
The surface-form file extension changes from .ailx to .ail. AILang's
authoring surface now uses the same .ail stem as its canonical JSON
form (.ail.json), giving the language a single coherent extension
family: .ail is the LLM-authored Form A, .ail.json is the canonical
JSON-AST Form B.
Scope (touched):
- 61 example renames examples/**/*.ailx → .ail (git mv)
- 1 rename experiments/.../rendered/ailx.md → ail.md
- 35 content-edited live-toolchain files (crates/, docs/DESIGN.md,
docs/roadmap.md, docs/PROSE_ROUNDTRIP.md, skills/, bench/reference/*.c,
experiment crates under experiments/.../{render,harness,master})
- Experiment-crate cohort rename Cohort::Ailx → Cohort::Ail,
Form::Ailx → Form::Ail, per_cohort/ailx → per_cohort/ail,
{form-only: ailx} → {form-only: ail}, ```ailx → ```ail
Out of scope (deliberately untouched, to preserve honest history):
- docs/journal-archive.md (content-frozen per CLAUDE.md)
- docs/journals/, docs/specs/, docs/plans/, bench/orchestrator-stats/
- experiments/.../runs/ (frozen LLM-output artefacts; models actually
saw .ailx — renaming would falsify the experimental record)
Verification: cargo build/test --workspace green; experiment crate
cargo test green; bench/check.py + compile_check.py + cross_lang.py
all 0-regressed; negative grep for ailx|Ailx|AILX outside the
out-of-scope paths returns zero matches.
Opens immediate follow-up: roadmap.md P2 todo `ail check`/build/run
accept .ail extension — after this rename, .ail is canonical
authoring surface but the CLI still produces a misleading JSON-parse
error on `ail check foo.ail`. That's the next iter.
197 lines
5.7 KiB
Plaintext
197 lines
5.7 KiB
Plaintext
; Iter 15b — second stdlib module: polymorphic singly-linked lists.
|
|
; Imports std_maybe so head/tail can return Maybe<a> / Maybe<List<a>>.
|
|
; All cross-module references use the qualified form per the Iter 14h
|
|
; convention: `std_maybe.Maybe` at type-name slots, `std_maybe.from_maybe`
|
|
; for fns. Bare ctor names (`Just`, `Nothing`) stay unqualified — once
|
|
; the type is resolved the ctor lookup is unambiguous.
|
|
|
|
(module std_list
|
|
|
|
(import std_maybe)
|
|
|
|
(data List (vars a)
|
|
(doc "Polymorphic singly-linked list: Nil or Cons<a, List<a>>.")
|
|
(ctor Nil)
|
|
(ctor Cons a (con List a)))
|
|
|
|
(fn fold_left
|
|
(doc "Tail-recursive left fold. The recursive call is in tail position and is marked.")
|
|
(type
|
|
(forall (vars a b)
|
|
(fn-type
|
|
(params (fn-type (params b a) (ret b))
|
|
b
|
|
(con List a))
|
|
(ret b))))
|
|
(params f acc xs)
|
|
(body
|
|
(match xs
|
|
(case (pat-ctor Nil) acc)
|
|
(case (pat-ctor Cons h t)
|
|
(tail-app fold_left f (app f acc h) t)))))
|
|
|
|
(fn fold_right
|
|
(doc "Right fold. Constructor-blocked: the recursive call is the second arg of f, NOT a tail position.")
|
|
(type
|
|
(forall (vars a b)
|
|
(fn-type
|
|
(params (fn-type (params a b) (ret b))
|
|
b
|
|
(con List a))
|
|
(ret b))))
|
|
(params f acc xs)
|
|
(body
|
|
(match xs
|
|
(case (pat-ctor Nil) acc)
|
|
(case (pat-ctor Cons h t)
|
|
(app f h (app fold_right f acc t))))))
|
|
|
|
(fn length
|
|
(doc "Length via fold_left. The accumulating lambda ignores the element and increments the counter.")
|
|
(type
|
|
(forall (vars a)
|
|
(fn-type
|
|
(params (con List a))
|
|
(ret (con Int)))))
|
|
(params xs)
|
|
(body
|
|
(app fold_left
|
|
(lam (params (typed c (con Int)) (typed _ a))
|
|
(ret (con Int))
|
|
(body (app + c 1)))
|
|
0
|
|
xs)))
|
|
|
|
(fn reverse
|
|
(doc "Reverse via fold_left with a flipping accumulator. Tail-recursive by virtue of the fold_left call.")
|
|
(type
|
|
(forall (vars a)
|
|
(fn-type
|
|
(params (con List a))
|
|
(ret (con List a)))))
|
|
(params xs)
|
|
(body
|
|
(app fold_left
|
|
(lam (params (typed acc (con List a)) (typed h a))
|
|
(ret (con List a))
|
|
(body (term-ctor List Cons h acc)))
|
|
(term-ctor List Nil)
|
|
xs)))
|
|
|
|
(fn is_empty
|
|
(doc "True iff the list is Nil.")
|
|
(type
|
|
(forall (vars a)
|
|
(fn-type
|
|
(params (con List a))
|
|
(ret (con Bool)))))
|
|
(params xs)
|
|
(body
|
|
(match xs
|
|
(case (pat-ctor Nil) true)
|
|
(case (pat-ctor Cons _ _) false))))
|
|
|
|
(fn head
|
|
(doc "Returns Just<a> of the first element, or Nothing for an empty list. Cross-module Maybe.")
|
|
(type
|
|
(forall (vars a)
|
|
(fn-type
|
|
(params (con List a))
|
|
(ret (con std_maybe.Maybe a)))))
|
|
(params xs)
|
|
(body
|
|
(match xs
|
|
(case (pat-ctor Nil) (term-ctor std_maybe.Maybe Nothing))
|
|
(case (pat-ctor Cons h _) (term-ctor std_maybe.Maybe Just h)))))
|
|
|
|
(fn tail
|
|
(doc "Returns Just<List<a>> of the tail, or Nothing for an empty list.")
|
|
(type
|
|
(forall (vars a)
|
|
(fn-type
|
|
(params (con List a))
|
|
(ret (con std_maybe.Maybe (con List a))))))
|
|
(params xs)
|
|
(body
|
|
(match xs
|
|
(case (pat-ctor Nil) (term-ctor std_maybe.Maybe Nothing))
|
|
(case (pat-ctor Cons _ t) (term-ctor std_maybe.Maybe Just t)))))
|
|
|
|
(fn append
|
|
(doc "Concatenate two lists. Constructor-blocked recursion: the recursive call is inside Cons, NOT a tail.")
|
|
(type
|
|
(forall (vars a)
|
|
(fn-type
|
|
(params (con List a) (con List a))
|
|
(ret (con List a)))))
|
|
(params xs ys)
|
|
(body
|
|
(match xs
|
|
(case (pat-ctor Nil) ys)
|
|
(case (pat-ctor Cons h t)
|
|
(term-ctor List Cons h (app append t ys))))))
|
|
|
|
(fn map
|
|
(doc "Polymorphic map. Constructor-blocked recursion.")
|
|
(type
|
|
(forall (vars a b)
|
|
(fn-type
|
|
(params (fn-type (params a) (ret b))
|
|
(con List a))
|
|
(ret (con List b)))))
|
|
(params f xs)
|
|
(body
|
|
(match xs
|
|
(case (pat-ctor Nil) (term-ctor List Nil))
|
|
(case (pat-ctor Cons h t)
|
|
(term-ctor List Cons (app f h) (app map f t))))))
|
|
|
|
(fn filter
|
|
(doc "Keep elements where p is true. Constructor-blocked when p holds; non-tail recursive call when p is false.")
|
|
(type
|
|
(forall (vars a)
|
|
(fn-type
|
|
(params (fn-type (params a) (ret (con Bool)))
|
|
(con List a))
|
|
(ret (con List a)))))
|
|
(params p xs)
|
|
(body
|
|
(match xs
|
|
(case (pat-ctor Nil) (term-ctor List Nil))
|
|
(case (pat-ctor Cons h t)
|
|
(if (app p h)
|
|
(term-ctor List Cons h (app filter p t))
|
|
(app filter p t))))))
|
|
|
|
(fn take
|
|
(doc "First n elements of xs (or all of xs if it has fewer than n).")
|
|
(type
|
|
(forall (vars a)
|
|
(fn-type
|
|
(params (con Int) (con List a))
|
|
(ret (con List a)))))
|
|
(params n xs)
|
|
(body
|
|
(if (app <= n 0)
|
|
(term-ctor List Nil)
|
|
(match xs
|
|
(case (pat-ctor Nil) (term-ctor List Nil))
|
|
(case (pat-ctor Cons h t)
|
|
(term-ctor List Cons h (app take (app - n 1) t)))))))
|
|
|
|
(fn drop
|
|
(doc "All elements of xs after the first n (or Nil if xs has fewer than n elements).")
|
|
(type
|
|
(forall (vars a)
|
|
(fn-type
|
|
(params (con Int) (con List a))
|
|
(ret (con List a)))))
|
|
(params n xs)
|
|
(body
|
|
(if (app <= n 0)
|
|
xs
|
|
(match xs
|
|
(case (pat-ctor Nil) (term-ctor List Nil))
|
|
(case (pat-ctor Cons _ t)
|
|
(app drop (app - n 1) t)))))))
|