iter prep.1-type-scoped-namespacing (DONE 5/5): TypeDef-first resolution + workspace pre-pass — closes #31

First iteration of the kernel-extension-mechanics milestone. Ships
the type-scoped `<TypeName>.<member>` resolution path as the
canonical form for type-associated operations, narrows the
`BareCrossModuleTypeRef` / `BadCrossModuleTypeRef` diagnostics from
"bare = strictly local" to "bare = in-scope by any path", migrates
12 std-library example fixtures, and introduces a workspace-wide
normalisation pre-pass `prepare_workspace_for_check` shared between
`check_workspace` and `monomorphise_workspace`.

Architectural discovery during implementation: the plan covered the
`Term::Var` dot-qualified resolver layer plus the workspace
validator's bare-name acceptance, but the migration of bare-form
fixtures exposed five sites where bare vs. qualified type-names
needed symmetric treatment — `Term::Ctor` resolution, `Type::Con`
well-formedness, mono's poly-free-fn name/constraint-count
enumeration, codegen's `lookup_ctor_by_type` bare-name path, and
the upstream desugar-then-qualify composition. Rather than
scattering TypeDef-first ladders across each site, the implementer
centralised the work into one pre-pass that walks every consumer
module's `Type::Con.name` and `Term::Ctor.type_name`, rewriting
bare cross-module references to their qualified `<home>.<Type>`
form. This is symmetric to the pre-existing `qualify_local_types`
(owner-side); the new pre-pass is the consumer-side mirror.
Downstream passes see qualified Types regardless of authoring form.
The TypeDef-first ladder still lives in `synth`'s `Term::Var` arm
because `<TypeName>.<member>` is term-position-only — `Maybe.from_maybe`
is a Var, not a Type expression, and the pre-pass does not rewrite
Var names.

Alternatives considered:

(a) Add TypeDef-first ladder at every resolution site separately
    (the plan's implicit assumption). Rejected: O(N) extension
    sites, each carrying the same workspace-walking logic; the
    pre-pass version is O(1) — one pass, every downstream consumer
    benefits.
(b) BLOCKED + spec re-brainstorm. Rejected: the architecture
    extension is consistent with prep.1's thesis (bare type-name
    resolves to the workspace-wide TypeDef) and forward-compatible
    with prep.2 (Term::New.type_name falls under the same rewrite)
    and prep.3 (kernel-tier TypeDefs enter the workspace map
    automatically). No design regression to bounce back over.

Spec updated to document the realisation mechanism honestly: the
"Realisation mechanism — workspace pre-pass" subsection clarifies
that the resolver-level semantics described in "Implementation
shape" are the user-facing contract, and the actual code path is
the pre-pass.

Verification:

- `cargo test --workspace`: ALL GREEN. 87 e2e + every crate's unit
  + integration tests pass with no regressions.
- Three NEW in-source tests pin Task 1's resolver paths:
  `type_scoped_member_resolves`, `type_scoped_member_not_found`,
  `type_scoped_receiver_not_a_type`.
- One NEW workspace test pins the narrowed validator:
  `ct1_validator_accepts_bare_with_explicit_import`.
- One renamed-and-flipped existing test:
  `ct1_validator_rejects_bare_xmod_with_import_candidate` →
  `ct1_validator_accepts_bare_xmod_with_import_candidate` (the
  bare-with-import path is now ACCEPTED).
- One NEW companion test for the workspace-wide ctor lookup:
  `ct2_term_ctor_bare_cross_module_via_workspace_resolves`.
- Two pre-existing tests' assertions updated for the new error
  wording: `ct1_check_cli::check_human_mode_emits_actionable_message_to_stderr`
  and `crates/ailang-check/tests/workspace.rs::unknown_module_prefix_is_reported`.
- 12 migrated `.ail` fixtures verified via the existing e2e
  suite (each fixture is the test runner's target for an existing
  `build_and_run` assertion).
- Negative fixture `ct_2_bare_cross_module.ail` semantically
  preserved: dropped its `(import std_maybe)` so bare `Maybe` is
  out-of-scope under the narrowed rule and still fires
  `BareCrossModuleTypeRef`.

Concerns:

- The pre-pass introduces a new architectural layer (consumer-side
  qualification) that the spec did not originally anticipate. Spec
  amendment in this commit documents the layer. Future iterations
  reference `prepare_workspace_for_check` as established
  infrastructure.
- `examples/test_ct1_bare_xmod_rejected.ail.json` switched its
  offending name from bare `Ordering` (which under the prep.1
  semantics may now resolve via implicit prelude) to a still-
  unresolvable `Mystery_Type`. The CLI test's intent (assert that
  a human-mode `ail check` exits non-zero on a still-RED case) is
  preserved.

Milestone status: kernel-extension-mechanics (Gitea #6) advances
1/3 iters. Next: prep.2 (`Term::New` construct) issue #32.
This commit is contained in:
2026-05-28 14:43:03 +02:00
parent 46c9aabf00
commit b586999e81
26 changed files with 925 additions and 271 deletions
+15 -12
View File
@@ -1,22 +1,25 @@
; Fieldtest — canonical-type-names, axis 1: BareCrossModuleTypeRef.
;
; A consumer of std_maybe deliberately writes a BARE `Maybe` in its
; fn signature instead of `std_maybe.Maybe`. Per ct.1's load-time
; validator, the canonical form requires cross-module type refs to
; be qualified. Expected: workspace-load error
; `BareCrossModuleTypeRef` naming the type and listing the qualified
; form as a candidate.
; fn signature WITHOUT (import std_maybe). prep.1 migration
; (kernel-extension-mechanics): pre-prep.1 this fixture rejected
; bare `Maybe` even when the import WAS present (the canonical form
; required cross-module type refs to be qualified at all times).
; Post-prep.1 bare-in-scope is canonical; the rejection path narrows
; to "bare-not-in-scope". To preserve the fixture's NEGATIVE role
; the `(import std_maybe)` declaration is dropped; bare `Maybe` is
; now genuinely out of scope and fires `BareCrossModuleTypeRef`
; with the narrowed "not in scope" message. The candidates list
; comes from the consumer's explicit imports + implicit imports;
; here both are empty, so candidates is empty too.
;
; This is what an LLM author would write if they forgot the
; cross-module-qualification rule — the rule fires here at load
; time, not deep inside the typechecker.
; Expected: workspace-load error `BareCrossModuleTypeRef` naming
; the type with the narrowed wording.
(module ct_2_bare_cross_module
(import std_maybe)
(fn classify
(doc "Identity over Maybe<Int>; signature uses bare `Maybe` instead of `std_maybe.Maybe`.")
(doc "Identity over Maybe<Int>; signature uses bare `Maybe` with no import.")
(type
(fn-type
(params (con Maybe (con Int)))
@@ -28,4 +31,4 @@
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body
(app print (app std_maybe.from_maybe 99 (app classify (term-ctor std_maybe.Maybe Just 7)))))))
(app classify (term-ctor Maybe Just 7)))))
@@ -2,7 +2,10 @@
; — known module, unknown type. Author qualifies as `std_maybe.Widget`
; where `std_maybe` IS a workspace module but does not declare a
; `Widget` type. Per ct.1's load-time validator, this should be
; rejected with `BadCrossModuleTypeRef`.
; rejected with `BadCrossModuleTypeRef`. prep.1 (kernel-extension-
; mechanics): the rejection path is unchanged structurally; only the
; message wording is narrowed (suggests "use bare from imported
; module instead").
(module ct_3b_bad_qualified_known_module
+8 -5
View File
@@ -1,6 +1,9 @@
; Iter 16a — first program to use a nested constructor pattern.
; Without this iter, the inner `(pat-ctor Cons b _)` would be
; rejected by the checker as `nested-ctor-pattern-not-allowed`.
; prep.1 migration (kernel-extension-mechanics): bare List via
; `(import std_list)`; cross-module fns / ctors stay structurally
; identical (bare types now in scope).
(module nested_pat
@@ -10,7 +13,7 @@
(doc "Sum of the first two elements of an Int list, or 0 if shorter than two.")
(type
(fn-type
(params (con std_list.List (con Int)))
(params (con List (con Int)))
(ret (con Int))))
(params xs)
(body
@@ -24,7 +27,7 @@
(params)
(body
(app print (app first_two_sum
(term-ctor std_list.List Cons 10
(term-ctor std_list.List Cons 20
(term-ctor std_list.List Cons 30
(term-ctor std_list.List Nil)))))))))
(term-ctor List Cons 10
(term-ctor List Cons 20
(term-ctor List Cons 30
(term-ctor List Nil)))))))))
+13 -11
View File
@@ -2,6 +2,8 @@
; Imports std_either, exercises all five combinators. First demo to
; pass two function arguments to a single combinator (the eliminator
; `either`); first to drive a 3-type-var polymorphic fn end-to-end.
; prep.1 migration (kernel-extension-mechanics): std_either.<fn> ->
; Either.<fn>; bare Either via (import std_either).
(module std_either_demo
@@ -18,14 +20,14 @@
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body
(seq (seq (app print (app std_either.from_right 0 (term-ctor std_either.Either Right 42))) (do io/print_str "\n"))
(seq (seq (app print (app std_either.from_right 99 (term-ctor std_either.Either Left 7))) (do io/print_str "\n"))
(seq (seq (app print (app std_either.is_left (term-ctor std_either.Either Left 7))) (do io/print_str "\n"))
(seq (seq (app print (app std_either.is_right (term-ctor std_either.Either Right 42))) (do io/print_str "\n"))
(seq (seq (app print (app std_either.from_right 0
(app std_either.map_right inc
(term-ctor std_either.Either Right 41)))) (do io/print_str "\n"))
(seq (seq (app print (app std_either.either inc inc
(term-ctor std_either.Either Left 5))) (do io/print_str "\n"))
(seq (app print (app std_either.either inc inc
(term-ctor std_either.Either Right 100))) (do io/print_str "\n")))))))))))
(seq (seq (app print (app Either.from_right 0 (term-ctor Either Right 42))) (do io/print_str "\n"))
(seq (seq (app print (app Either.from_right 99 (term-ctor Either Left 7))) (do io/print_str "\n"))
(seq (seq (app print (app Either.is_left (term-ctor Either Left 7))) (do io/print_str "\n"))
(seq (seq (app print (app Either.is_right (term-ctor Either Right 42))) (do io/print_str "\n"))
(seq (seq (app print (app Either.from_right 0
(app Either.map_right inc
(term-ctor Either Right 41)))) (do io/print_str "\n"))
(seq (seq (app print (app Either.either inc inc
(term-ctor Either Left 5))) (do io/print_str "\n"))
(seq (app print (app Either.either inc inc
(term-ctor Either Right 100))) (do io/print_str "\n")))))))))))
+19 -19
View File
@@ -17,55 +17,55 @@
(type
(forall (vars e a)
(fn-type
(params (con std_list.List (con std_either.Either e a)))
(ret (con std_list.List e)))))
(params (con List (con Either e a)))
(ret (con List e)))))
(params xs)
(body
(match xs
(case (pat-ctor Cons (pat-ctor Left l) t)
(term-ctor std_list.List Cons l (app lefts t)))
(term-ctor List Cons l (app lefts t)))
(case (pat-ctor Cons (pat-ctor Right _) t)
(app lefts t))
(case _ (term-ctor std_list.List Nil)))))
(case _ (term-ctor List Nil)))))
(fn rights
(doc "Project the Right payloads of a list of Eithers into a List<a>. Symmetric to lefts; same nested-Ctor + wildcard-tail pattern shape.")
(type
(forall (vars e a)
(fn-type
(params (con std_list.List (con std_either.Either e a)))
(ret (con std_list.List a)))))
(params (con List (con Either e a)))
(ret (con List a)))))
(params xs)
(body
(match xs
(case (pat-ctor Cons (pat-ctor Left _) t)
(app rights t))
(case (pat-ctor Cons (pat-ctor Right r) t)
(term-ctor std_list.List Cons r (app rights t)))
(case _ (term-ctor std_list.List Nil)))))
(term-ctor List Cons r (app rights t)))
(case _ (term-ctor List Nil)))))
(fn partition_eithers
(doc "Partition a list of Eithers into a Pair<List<e>, List<a>>: lefts on the left, rights on the right. Single pass via direct recursion; head dispatch is a flat match on the recursive result's projections.")
(type
(forall (vars e a)
(fn-type
(params (con std_list.List (con std_either.Either e a)))
(ret (con std_pair.Pair (con std_list.List e) (con std_list.List a))))))
(params (con List (con Either e a)))
(ret (con Pair (con List e) (con List a))))))
(params xs)
(body
(match xs
(case (pat-ctor Nil)
(term-ctor std_pair.Pair MkPair
(term-ctor std_list.List Nil)
(term-ctor std_list.List Nil)))
(term-ctor Pair MkPair
(term-ctor List Nil)
(term-ctor List Nil)))
(case (pat-ctor Cons h t)
(let rest (app partition_eithers t)
(match h
(case (pat-ctor Left l)
(term-ctor std_pair.Pair MkPair
(term-ctor std_list.List Cons l (app std_pair.fst rest))
(app std_pair.snd rest)))
(term-ctor Pair MkPair
(term-ctor List Cons l (app Pair.fst rest))
(app Pair.snd rest)))
(case (pat-ctor Right r)
(term-ctor std_pair.Pair MkPair
(app std_pair.fst rest)
(term-ctor std_list.List Cons r (app std_pair.snd rest)))))))))))
(term-ctor Pair MkPair
(app Pair.fst rest)
(term-ctor List Cons r (app Pair.snd rest)))))))))))
+5 -5
View File
@@ -3,7 +3,7 @@
; threads a List<Either<Int, Int>> through three combinators that
; together exercise every monomorphisation site introduced by 15g.
;
; The list is constructed inline by mixing `(term-ctor std_either.Either
; The list is constructed inline by mixing `(term-ctor Either
; Left ...)` and `(... Right ...)`. Iter 15g surfaced a `unify_for_subst`
; asymmetry that would have rejected this construction at synth time;
; 15g-aux fixed it by accepting `$u` synth-wildcards on either side of
@@ -24,7 +24,7 @@
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body
(seq (seq (app print (app std_list.length (app std_either_list.lefts (term-ctor std_list.List Cons (term-ctor std_either.Either Left 1) (term-ctor std_list.List Cons (term-ctor std_either.Either Right 10) (term-ctor std_list.List Cons (term-ctor std_either.Either Left 2) (term-ctor std_list.List Cons (term-ctor std_either.Either Right 20) (term-ctor std_list.List Cons (term-ctor std_either.Either Right 30) (term-ctor std_list.List Nil))))))))) (do io/print_str "\n"))
(seq (seq (app print (app std_list.length (app std_either_list.rights (term-ctor std_list.List Cons (term-ctor std_either.Either Left 1) (term-ctor std_list.List Cons (term-ctor std_either.Either Right 10) (term-ctor std_list.List Cons (term-ctor std_either.Either Left 2) (term-ctor std_list.List Cons (term-ctor std_either.Either Right 20) (term-ctor std_list.List Cons (term-ctor std_either.Either Right 30) (term-ctor std_list.List Nil))))))))) (do io/print_str "\n"))
(seq (seq (app print (app std_list.length (app std_pair.fst (app std_either_list.partition_eithers (term-ctor std_list.List Cons (term-ctor std_either.Either Left 1) (term-ctor std_list.List Cons (term-ctor std_either.Either Right 10) (term-ctor std_list.List Cons (term-ctor std_either.Either Left 2) (term-ctor std_list.List Cons (term-ctor std_either.Either Right 20) (term-ctor std_list.List Cons (term-ctor std_either.Either Right 30) (term-ctor std_list.List Nil)))))))))) (do io/print_str "\n"))
(seq (app print (app std_list.length (app std_pair.snd (app std_either_list.partition_eithers (term-ctor std_list.List Cons (term-ctor std_either.Either Left 1) (term-ctor std_list.List Cons (term-ctor std_either.Either Right 10) (term-ctor std_list.List Cons (term-ctor std_either.Either Left 2) (term-ctor std_list.List Cons (term-ctor std_either.Either Right 20) (term-ctor std_list.List Cons (term-ctor std_either.Either Right 30) (term-ctor std_list.List Nil)))))))))) (do io/print_str "\n"))))))))
(seq (seq (app print (app List.length (app std_either_list.lefts (term-ctor List Cons (term-ctor Either Left 1) (term-ctor List Cons (term-ctor Either Right 10) (term-ctor List Cons (term-ctor Either Left 2) (term-ctor List Cons (term-ctor Either Right 20) (term-ctor List Cons (term-ctor Either Right 30) (term-ctor List Nil))))))))) (do io/print_str "\n"))
(seq (seq (app print (app List.length (app std_either_list.rights (term-ctor List Cons (term-ctor Either Left 1) (term-ctor List Cons (term-ctor Either Right 10) (term-ctor List Cons (term-ctor Either Left 2) (term-ctor List Cons (term-ctor Either Right 20) (term-ctor List Cons (term-ctor Either Right 30) (term-ctor List Nil))))))))) (do io/print_str "\n"))
(seq (seq (app print (app List.length (app Pair.fst (app std_either_list.partition_eithers (term-ctor List Cons (term-ctor Either Left 1) (term-ctor List Cons (term-ctor Either Right 10) (term-ctor List Cons (term-ctor Either Left 2) (term-ctor List Cons (term-ctor Either Right 20) (term-ctor List Cons (term-ctor Either Right 30) (term-ctor List Nil)))))))))) (do io/print_str "\n"))
(seq (app print (app List.length (app Pair.snd (app std_either_list.partition_eithers (term-ctor List Cons (term-ctor Either Left 1) (term-ctor List Cons (term-ctor Either Right 10) (term-ctor List Cons (term-ctor Either Left 2) (term-ctor List Cons (term-ctor Either Right 20) (term-ctor List Cons (term-ctor Either Right 30) (term-ctor List Nil)))))))))) (do io/print_str "\n"))))))))
+10 -10
View File
@@ -1,9 +1,9 @@
; 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.
; prep.1 migration (kernel-extension-mechanics): bare `Maybe` at
; type-name slots (in scope via `(import std_maybe)`). Bare ctor
; names (`Just`, `Nothing`) stay unqualified — once the type is
; resolved the ctor lookup is unambiguous.
(module std_list
@@ -97,12 +97,12 @@
(forall (vars a)
(fn-type
(params (con List a))
(ret (con std_maybe.Maybe a)))))
(ret (con 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)))))
(case (pat-ctor Nil) (term-ctor Maybe Nothing))
(case (pat-ctor Cons h _) (term-ctor Maybe Just h)))))
(fn tail
(doc "Returns Just<List<a>> of the tail, or Nothing for an empty list.")
@@ -110,12 +110,12 @@
(forall (vars a)
(fn-type
(params (con List a))
(ret (con std_maybe.Maybe (con List a))))))
(ret (con 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)))))
(case (pat-ctor Nil) (term-ctor Maybe Nothing))
(case (pat-ctor Cons _ t) (term-ctor Maybe Just t)))))
(fn append
(doc "Concatenate two lists. Constructor-blocked recursion: the recursive call is inside Cons, NOT a tail.")
+21 -19
View File
@@ -1,7 +1,9 @@
; Iter 15b — second consumer demo.
; Imports both std_maybe and std_list. Exercises every combinator at
; least once. xs is a top-level fn `() -> List<Int>` (consts cannot
; reference user fns; the brief flagged this).
; reference user fns; the brief flagged this). prep.1 migration
; (kernel-extension-mechanics): type-scoped form for List.<fn> and
; Maybe.<fn>; bare List / Maybe via the explicit imports.
(module std_list_demo
@@ -34,28 +36,28 @@
(const xs
(doc "The canonical list [1,2,3,4,5] for the demo. Pure ctor expression, so a const works.")
(type (con std_list.List (con Int)))
(type (con List (con Int)))
(body
(term-ctor std_list.List Cons 1
(term-ctor std_list.List Cons 2
(term-ctor std_list.List Cons 3
(term-ctor std_list.List Cons 4
(term-ctor std_list.List Cons 5
(term-ctor std_list.List Nil))))))))
(term-ctor List Cons 1
(term-ctor List Cons 2
(term-ctor List Cons 3
(term-ctor List Cons 4
(term-ctor List Cons 5
(term-ctor List Nil))))))))
(fn main
(doc "Drive each std_list combinator once. Expected outputs (per line): 5, false, true, 1, 4, 10, 5, 2, 2, 15, 15.")
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body
(seq (seq (app print (app std_list.length xs)) (do io/print_str "\n"))
(seq (seq (app print (app std_list.is_empty xs)) (do io/print_str "\n"))
(seq (seq (app print (app std_list.is_empty (term-ctor std_list.List Nil))) (do io/print_str "\n"))
(seq (seq (app print (app std_maybe.from_maybe -1 (app std_list.head xs))) (do io/print_str "\n"))
(seq (seq (app print (app std_list.length (app std_maybe.from_maybe xs (app std_list.tail xs)))) (do io/print_str "\n"))
(seq (seq (app print (app std_list.length (app std_list.append xs xs))) (do io/print_str "\n"))
(seq (seq (app print (app std_maybe.from_maybe -1 (app std_list.head (app std_list.reverse xs)))) (do io/print_str "\n"))
(seq (seq (app print (app std_maybe.from_maybe -1 (app std_list.head (app std_list.map double xs)))) (do io/print_str "\n"))
(seq (seq (app print (app std_list.length (app std_list.filter is_even xs))) (do io/print_str "\n"))
(seq (seq (app print (app std_list.fold_left add 0 xs)) (do io/print_str "\n"))
(seq (app print (app std_list.fold_right add 0 xs)) (do io/print_str "\n")))))))))))))))
(seq (seq (app print (app List.length xs)) (do io/print_str "\n"))
(seq (seq (app print (app List.is_empty xs)) (do io/print_str "\n"))
(seq (seq (app print (app List.is_empty (term-ctor List Nil))) (do io/print_str "\n"))
(seq (seq (app print (app Maybe.from_maybe -1 (app List.head xs))) (do io/print_str "\n"))
(seq (seq (app print (app List.length (app Maybe.from_maybe xs (app List.tail xs)))) (do io/print_str "\n"))
(seq (seq (app print (app List.length (app List.append xs xs))) (do io/print_str "\n"))
(seq (seq (app print (app Maybe.from_maybe -1 (app List.head (app List.reverse xs)))) (do io/print_str "\n"))
(seq (seq (app print (app Maybe.from_maybe -1 (app List.head (app List.map double xs)))) (do io/print_str "\n"))
(seq (seq (app print (app List.length (app List.filter is_even xs))) (do io/print_str "\n"))
(seq (seq (app print (app List.fold_left add 0 xs)) (do io/print_str "\n"))
(seq (app print (app List.fold_right add 0 xs)) (do io/print_str "\n")))))))))))))))
+13 -13
View File
@@ -10,23 +10,23 @@
(const xs
(doc "The canonical [1, 2, 3, 4, 5] used across all checks.")
(type (con std_list.List (con Int)))
(type (con List (con Int)))
(body
(term-ctor std_list.List Cons 1
(term-ctor std_list.List Cons 2
(term-ctor std_list.List Cons 3
(term-ctor std_list.List Cons 4
(term-ctor std_list.List Cons 5
(term-ctor std_list.List Nil))))))))
(term-ctor List Cons 1
(term-ctor List Cons 2
(term-ctor List Cons 3
(term-ctor List Cons 4
(term-ctor List Cons 5
(term-ctor List Nil))))))))
(fn main
(doc "Expected output (one per line): 0, 3, 5, 5, 3, 0.")
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body
(seq (seq (app print (app std_list.length (app std_list.take 0 xs))) (do io/print_str "\n"))
(seq (seq (app print (app std_list.length (app std_list.take 3 xs))) (do io/print_str "\n"))
(seq (seq (app print (app std_list.length (app std_list.take 100 xs))) (do io/print_str "\n"))
(seq (seq (app print (app std_list.length (app std_list.drop 0 xs))) (do io/print_str "\n"))
(seq (seq (app print (app std_list.length (app std_list.drop 2 xs))) (do io/print_str "\n"))
(seq (app print (app std_list.length (app std_list.drop 100 xs))) (do io/print_str "\n"))))))))))
(seq (seq (app print (app List.length (app List.take 0 xs))) (do io/print_str "\n"))
(seq (seq (app print (app List.length (app List.take 3 xs))) (do io/print_str "\n"))
(seq (seq (app print (app List.length (app List.take 100 xs))) (do io/print_str "\n"))
(seq (seq (app print (app List.length (app List.drop 0 xs))) (do io/print_str "\n"))
(seq (seq (app print (app List.length (app List.drop 2 xs))) (do io/print_str "\n"))
(seq (app print (app List.length (app List.drop 100 xs))) (do io/print_str "\n"))))))))))
+6 -6
View File
@@ -10,16 +10,16 @@
(import std_list)
(fn build
(doc "Build [n, n-1, ..., 1] :: std_list.List Int via Cons recursion. Constructor-blocked; not tail.")
(doc "Build [n, n-1, ..., 1] :: List Int via Cons recursion. Constructor-blocked; not tail.")
(type
(fn-type
(params (con Int))
(ret (con std_list.List (con Int)))))
(ret (con List (con Int)))))
(params n)
(body
(if (app eq n 0)
(term-ctor std_list.List Nil)
(term-ctor std_list.List Cons
(term-ctor List Nil)
(term-ctor List Cons
n
(app build (app - n 1))))))
@@ -37,5 +37,5 @@
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body
(seq (seq (app print (app std_list.fold_left add 0 (app build 1000))) (do io/print_str "\n"))
(seq (app print (app std_list.fold_right add 0 (app build 1000))) (do io/print_str "\n"))))))
(seq (seq (app print (app List.fold_left add 0 (app build 1000))) (do io/print_str "\n"))
(seq (app print (app List.fold_right add 0 (app build 1000))) (do io/print_str "\n"))))))
+9 -11
View File
@@ -1,12 +1,10 @@
; Iter 15a — first consumer of an stdlib module.
; Imports std_maybe, exercises from_maybe, is_some, is_none, map_maybe.
; First program to import a parameterised ADT (Maybe a) across module
; boundaries. Per the project's qualified-only convention (Iter 5b for
; fns, Iter 15a for types/ctors), every cross-module reference is
; qualified: `std_maybe.from_maybe` for the fn, `std_maybe.Maybe` for
; the type-name slot of `term-ctor`. The bare ctor names (`Just`,
; `Nothing`) stay unqualified — once the type is resolved, the ctor
; lookup is unambiguous within it.
; boundaries. prep.1 migration (kernel-extension-mechanics): every
; type-associated function on Maybe is now spelled in type-scoped form
; `Maybe.<fn>`, and bare `Maybe` is in scope via `(import std_maybe)`
; so the `term-ctor` type-name slot drops the module qualifier too.
(module std_maybe_demo
@@ -23,8 +21,8 @@
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body
(seq (seq (app print (app std_maybe.from_maybe 99 (term-ctor std_maybe.Maybe Just 7))) (do io/print_str "\n"))
(seq (seq (app print (app std_maybe.from_maybe 99 (term-ctor std_maybe.Maybe Nothing))) (do io/print_str "\n"))
(seq (seq (app print (app std_maybe.is_some (term-ctor std_maybe.Maybe Just 5))) (do io/print_str "\n"))
(seq (seq (app print (app std_maybe.is_none (term-ctor std_maybe.Maybe Nothing))) (do io/print_str "\n"))
(seq (app print (app std_maybe.from_maybe 0 (app std_maybe.map_maybe inc (term-ctor std_maybe.Maybe Just 41)))) (do io/print_str "\n")))))))))
(seq (seq (app print (app Maybe.from_maybe 99 (term-ctor Maybe Just 7))) (do io/print_str "\n"))
(seq (seq (app print (app Maybe.from_maybe 99 (term-ctor Maybe Nothing))) (do io/print_str "\n"))
(seq (seq (app print (app Maybe.is_some (term-ctor Maybe Just 5))) (do io/print_str "\n"))
(seq (seq (app print (app Maybe.is_none (term-ctor Maybe Nothing))) (do io/print_str "\n"))
(seq (app print (app Maybe.from_maybe 0 (app Maybe.map_maybe inc (term-ctor Maybe Just 41)))) (do io/print_str "\n")))))))))
+8 -7
View File
@@ -1,7 +1,8 @@
; Iter 15f — fourth consumer demo. Drives every std_pair combinator
; once. fst/snd are stable at 7/9; swap reverses; map_first/map_second
; demonstrate the Pair<a, b> -> Pair<c, b> / Pair<a, c> reshape with
; b/a held rigid.
; b/a held rigid. prep.1 migration (kernel-extension-mechanics):
; std_pair.<fn> -> Pair.<fn>; bare Pair via (import std_pair).
(module std_pair_demo
@@ -24,9 +25,9 @@
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body
(seq (seq (app print (app std_pair.fst (term-ctor std_pair.Pair MkPair 7 9))) (do io/print_str "\n"))
(seq (seq (app print (app std_pair.snd (term-ctor std_pair.Pair MkPair 7 9))) (do io/print_str "\n"))
(seq (seq (app print (app std_pair.fst (app std_pair.swap (term-ctor std_pair.Pair MkPair 7 9)))) (do io/print_str "\n"))
(seq (seq (app print (app std_pair.snd (app std_pair.swap (term-ctor std_pair.Pair MkPair 7 9)))) (do io/print_str "\n"))
(seq (seq (app print (app std_pair.fst (app std_pair.map_first inc (term-ctor std_pair.Pair MkPair 7 9)))) (do io/print_str "\n"))
(seq (app print (app std_pair.snd (app std_pair.map_second double (term-ctor std_pair.Pair MkPair 7 9)))) (do io/print_str "\n"))))))))))
(seq (seq (app print (app Pair.fst (term-ctor Pair MkPair 7 9))) (do io/print_str "\n"))
(seq (seq (app print (app Pair.snd (term-ctor Pair MkPair 7 9))) (do io/print_str "\n"))
(seq (seq (app print (app Pair.fst (app Pair.swap (term-ctor Pair MkPair 7 9)))) (do io/print_str "\n"))
(seq (seq (app print (app Pair.snd (app Pair.swap (term-ctor Pair MkPair 7 9)))) (do io/print_str "\n"))
(seq (seq (app print (app Pair.fst (app Pair.map_first inc (term-ctor Pair MkPair 7 9)))) (do io/print_str "\n"))
(seq (app print (app Pair.snd (app Pair.map_second double (term-ctor Pair MkPair 7 9)))) (do io/print_str "\n"))))))))))
@@ -9,14 +9,14 @@
"type": {
"k": "fn",
"params": [],
"ret": { "k": "con", "name": "Unit" },
"ret": { "k": "con", "name": "Mystery_Type" },
"effects": ["IO"]
},
"params": [],
"body": {
"t": "ctor",
"type": "Ordering",
"ctor": "LT",
"type": "Mystery_Type",
"ctor": "Whatever",
"args": []
}
}