12e9a9c0cc
The 15a tester surfaced a real compiler limitation: cross-module
type and ctor references were not implemented. Iter 5b only
carried fns + consts via module_globals; types/ctors stayed
module-local with an explicit DESIGN comment. This iter completes
the cross-module mechanism using the Iter-5b convention:
qualified-only access via module.Name.
Implementation:
- ailang-check: Env.module_types populated by build_module_types.
Qualified resolution in Type::Con, Term::Ctor, with cross-module
fallback for pat-ctor (local wins, multi-import collision -> new
ambiguous-ctor diagnostic). Four new unit tests.
- ailang-codegen: workspace-level module_ctor_index replaces
per-Emitter table. lookup_ctor_by_type / lookup_ctor_in_pattern
thread qualified type names through box-tag and field-type
resolution.
- examples/std_maybe_demo.{ailx,ail.json}: type-name slots now
qualified (std_maybe.Maybe).
- New e2e test cross_module_maybe_demo asserts the demo prints
["7","99","true","true","42"].
Net diff ~550 LOC. Tests 80 -> 85. All Iter 14a regressions
(parameterised_box_round_trip, parameterised_maybe_match,
list_map_poly_inc_then_prints, polymorphic_id_at_int_and_bool)
verified green — the 14h derive_substitution change (default
unpinned forall vars to Unit for monomorphiser) sits on a
different layer than 14a's $u-wildcard fix and they coexist.
Hash invariance: all five std_maybe def hashes unchanged. All
80-test-suite fixtures retain bit-identical hashes — cross-module
support is purely additive at the language level.
Process note: the std_maybe.ailx file landed in the 14g commit
via a sloppy git-add-A; should have spotted it before staging.
Not a correctness issue but a hygiene one.
Implementer flagged Unit-default monomorphisation as wasteful-
but-correct; rethink if stdlib grows toward overload-resolution-
style cases needing distinct unconstrained instantiations.
std_maybe stdlib effectively ships: module + four combinators +
e2e-tested consumer demo. Plan 15b: std_list importing std_maybe,
exercising Maybe-returning head/tail and tail-call-marked
fold_left.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 line
2.6 KiB
JSON
1 line
2.6 KiB
JSON
{"defs":[{"ctors":[{"fields":[],"name":"Nothing"},{"fields":[{"k":"var","name":"a"}],"name":"Just"}],"doc":"Polymorphic optional value: either Just<a> or Nothing.","kind":"type","name":"Maybe","vars":["a"]},{"body":{"arms":[{"body":{"name":"x","t":"var"},"pat":{"ctor":"Just","fields":[{"name":"x","p":"var"}],"p":"ctor"}},{"body":{"name":"default","t":"var"},"pat":{"ctor":"Nothing","fields":[],"p":"ctor"}}],"scrutinee":{"name":"m","t":"var"},"t":"match"},"doc":"Project out of Maybe<a> with a default for the Nothing case.","kind":"fn","name":"from_maybe","params":["default","m"],"type":{"body":{"effects":[],"k":"fn","params":[{"k":"var","name":"a"},{"args":[{"k":"var","name":"a"}],"k":"con","name":"Maybe"}],"ret":{"k":"var","name":"a"}},"k":"forall","vars":["a"]}},{"body":{"arms":[{"body":{"lit":{"kind":"bool","value":true},"t":"lit"},"pat":{"ctor":"Just","fields":[{"p":"wild"}],"p":"ctor"}},{"body":{"lit":{"kind":"bool","value":false},"t":"lit"},"pat":{"ctor":"Nothing","fields":[],"p":"ctor"}}],"scrutinee":{"name":"m","t":"var"},"t":"match"},"doc":"Returns true iff m is Just<_>.","kind":"fn","name":"is_some","params":["m"],"type":{"body":{"effects":[],"k":"fn","params":[{"args":[{"k":"var","name":"a"}],"k":"con","name":"Maybe"}],"ret":{"k":"con","name":"Bool"}},"k":"forall","vars":["a"]}},{"body":{"arms":[{"body":{"lit":{"kind":"bool","value":false},"t":"lit"},"pat":{"ctor":"Just","fields":[{"p":"wild"}],"p":"ctor"}},{"body":{"lit":{"kind":"bool","value":true},"t":"lit"},"pat":{"ctor":"Nothing","fields":[],"p":"ctor"}}],"scrutinee":{"name":"m","t":"var"},"t":"match"},"doc":"Returns true iff m is Nothing.","kind":"fn","name":"is_none","params":["m"],"type":{"body":{"effects":[],"k":"fn","params":[{"args":[{"k":"var","name":"a"}],"k":"con","name":"Maybe"}],"ret":{"k":"con","name":"Bool"}},"k":"forall","vars":["a"]}},{"body":{"arms":[{"body":{"args":[{"args":[{"name":"x","t":"var"}],"fn":{"name":"f","t":"var"},"t":"app"}],"ctor":"Just","t":"ctor","type":"Maybe"},"pat":{"ctor":"Just","fields":[{"name":"x","p":"var"}],"p":"ctor"}},{"body":{"args":[],"ctor":"Nothing","t":"ctor","type":"Maybe"},"pat":{"ctor":"Nothing","fields":[],"p":"ctor"}}],"scrutinee":{"name":"m","t":"var"},"t":"match"},"doc":"Apply f to the wrapped value, or pass Nothing through.","kind":"fn","name":"map_maybe","params":["f","m"],"type":{"body":{"effects":[],"k":"fn","params":[{"effects":[],"k":"fn","params":[{"k":"var","name":"a"}],"ret":{"k":"var","name":"b"}},{"args":[{"k":"var","name":"a"}],"k":"con","name":"Maybe"}],"ret":{"args":[{"k":"var","name":"b"}],"k":"con","name":"Maybe"}},"k":"forall","vars":["a","b"]}}],"imports":[],"name":"std_maybe","schema":"ailang/v0"} |