8d97a924de
Term::If was semantically a subset of Term::Match on Bool. Per CLAUDE.md the language must contain no redundancies; two AST nodes for the same operation produces an authoring decision with no semantic content and a duplicate codegen path. Removed. Migration shape (applied to sum, sort, max3 fixtures): (if c a b) -> (match c (case (lit-bool true) a) (case _ b)) No schema version bump (per user direction): no third-party consumes ailang/v0, so version ceremony is pure overhead. Edited AST and fixtures in place; pinned hashes in hash.rs updated. Implementer deviation, called out and justified: a tightly-scoped lower_bool_match helper (~95 LOC) was needed in codegen because the existing match path rejects i1 scrutinees and Pattern::Lit. Helper accepts only the canonical two-arm migration shape, errors on anything else, emits the same br/phi IR Term::If used to. No generalisation of the ADT-match codegen. Diff: 13 files, +286/-221 (net +65 LOC). AST got smaller (one variant gone), form-(A) got smaller (one production gone), typecheck got smaller (one branch gone). Codegen got slightly larger by the bool-match helper. Hash deltas: sum.sum, sort.insert, max3.max, max3.max3 changed. All other defs (e.g. sum.main, sort.IntList, sort.sort, sort.print_list, max3.main) kept bit-identical hashes — confirms canonical-JSON byte format intact. Verification: 76/76 tests green; sum->55, max3->17, sort->[1,1,2, 3,3,4,5,5,5,6,9] (identical to pre-migration). cargo doc 0 warnings. Tail-call survey by implementer (informs 14e): print_list recursions are already in tail position (rhs of seq inside match arm); map/sort/insert recursions are NOT (constructor-blocked inside Cons applications). 14e annotation will benefit terminal recursions; ctor-blocked ones need accumulator-form rewrites in source, not a compiler-side transform. Decision 7 added to DESIGN.md. JOURNAL entry has the language- completion sequence (14d done, 14e tail-calls, 14f GC, 15a stdlib). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
337 lines
11 KiB
JSON
337 lines
11 KiB
JSON
{
|
|
"schema": "ailang/v0",
|
|
"name": "sort",
|
|
"imports": [],
|
|
"defs": [
|
|
{
|
|
"kind": "type",
|
|
"name": "IntList",
|
|
"doc": "Singly-linked Int list, boxed.",
|
|
"ctors": [
|
|
{ "name": "Nil", "fields": [] },
|
|
{
|
|
"name": "Cons",
|
|
"fields": [
|
|
{ "k": "con", "name": "Int" },
|
|
{ "k": "con", "name": "IntList" }
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"kind": "fn",
|
|
"name": "insert",
|
|
"type": {
|
|
"k": "fn",
|
|
"params": [
|
|
{ "k": "con", "name": "Int" },
|
|
{ "k": "con", "name": "IntList" }
|
|
],
|
|
"ret": { "k": "con", "name": "IntList" },
|
|
"effects": []
|
|
},
|
|
"params": ["y", "xs"],
|
|
"doc": "Insert y into a sorted list xs, preserving order.",
|
|
"body": {
|
|
"t": "match",
|
|
"scrutinee": { "t": "var", "name": "xs" },
|
|
"arms": [
|
|
{
|
|
"pat": { "p": "ctor", "ctor": "Nil", "fields": [] },
|
|
"body": {
|
|
"t": "ctor",
|
|
"type": "IntList",
|
|
"ctor": "Cons",
|
|
"args": [
|
|
{ "t": "var", "name": "y" },
|
|
{
|
|
"t": "ctor",
|
|
"type": "IntList",
|
|
"ctor": "Nil",
|
|
"args": []
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"pat": {
|
|
"p": "ctor",
|
|
"ctor": "Cons",
|
|
"fields": [
|
|
{ "p": "var", "name": "h" },
|
|
{ "p": "var", "name": "t" }
|
|
]
|
|
},
|
|
"body": {
|
|
"t": "match",
|
|
"scrutinee": {
|
|
"t": "app",
|
|
"fn": { "t": "var", "name": "<=" },
|
|
"args": [
|
|
{ "t": "var", "name": "y" },
|
|
{ "t": "var", "name": "h" }
|
|
]
|
|
},
|
|
"arms": [
|
|
{
|
|
"pat": { "p": "lit", "lit": { "kind": "bool", "value": true } },
|
|
"body": {
|
|
"t": "ctor",
|
|
"type": "IntList",
|
|
"ctor": "Cons",
|
|
"args": [
|
|
{ "t": "var", "name": "y" },
|
|
{
|
|
"t": "ctor",
|
|
"type": "IntList",
|
|
"ctor": "Cons",
|
|
"args": [
|
|
{ "t": "var", "name": "h" },
|
|
{ "t": "var", "name": "t" }
|
|
]
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"pat": { "p": "wild" },
|
|
"body": {
|
|
"t": "ctor",
|
|
"type": "IntList",
|
|
"ctor": "Cons",
|
|
"args": [
|
|
{ "t": "var", "name": "h" },
|
|
{
|
|
"t": "app",
|
|
"fn": { "t": "var", "name": "insert" },
|
|
"args": [
|
|
{ "t": "var", "name": "y" },
|
|
{ "t": "var", "name": "t" }
|
|
]
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"kind": "fn",
|
|
"name": "sort",
|
|
"type": {
|
|
"k": "fn",
|
|
"params": [{ "k": "con", "name": "IntList" }],
|
|
"ret": { "k": "con", "name": "IntList" },
|
|
"effects": []
|
|
},
|
|
"params": ["xs"],
|
|
"doc": "Insertion sort: build the result by inserting each head into the sorted tail.",
|
|
"body": {
|
|
"t": "match",
|
|
"scrutinee": { "t": "var", "name": "xs" },
|
|
"arms": [
|
|
{
|
|
"pat": { "p": "ctor", "ctor": "Nil", "fields": [] },
|
|
"body": {
|
|
"t": "ctor",
|
|
"type": "IntList",
|
|
"ctor": "Nil",
|
|
"args": []
|
|
}
|
|
},
|
|
{
|
|
"pat": {
|
|
"p": "ctor",
|
|
"ctor": "Cons",
|
|
"fields": [
|
|
{ "p": "var", "name": "h" },
|
|
{ "p": "var", "name": "t" }
|
|
]
|
|
},
|
|
"body": {
|
|
"t": "app",
|
|
"fn": { "t": "var", "name": "insert" },
|
|
"args": [
|
|
{ "t": "var", "name": "h" },
|
|
{
|
|
"t": "app",
|
|
"fn": { "t": "var", "name": "sort" },
|
|
"args": [{ "t": "var", "name": "t" }]
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"kind": "fn",
|
|
"name": "print_list",
|
|
"type": {
|
|
"k": "fn",
|
|
"params": [{ "k": "con", "name": "IntList" }],
|
|
"ret": { "k": "con", "name": "Unit" },
|
|
"effects": ["IO"]
|
|
},
|
|
"params": ["xs"],
|
|
"body": {
|
|
"t": "match",
|
|
"scrutinee": { "t": "var", "name": "xs" },
|
|
"arms": [
|
|
{
|
|
"pat": { "p": "ctor", "ctor": "Nil", "fields": [] },
|
|
"body": { "t": "lit", "lit": { "kind": "unit" } }
|
|
},
|
|
{
|
|
"pat": {
|
|
"p": "ctor",
|
|
"ctor": "Cons",
|
|
"fields": [
|
|
{ "p": "var", "name": "h" },
|
|
{ "p": "var", "name": "t" }
|
|
]
|
|
},
|
|
"body": {
|
|
"t": "seq",
|
|
"lhs": {
|
|
"t": "do",
|
|
"op": "io/print_int",
|
|
"args": [{ "t": "var", "name": "h" }]
|
|
},
|
|
"rhs": {
|
|
"t": "app",
|
|
"fn": { "t": "var", "name": "print_list" },
|
|
"args": [{ "t": "var", "name": "t" }]
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"kind": "fn",
|
|
"name": "main",
|
|
"type": {
|
|
"k": "fn",
|
|
"params": [],
|
|
"ret": { "k": "con", "name": "Unit" },
|
|
"effects": ["IO"]
|
|
},
|
|
"params": [],
|
|
"doc": "Sort and print [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5].",
|
|
"body": {
|
|
"t": "let",
|
|
"name": "xs",
|
|
"value": {
|
|
"t": "ctor",
|
|
"type": "IntList",
|
|
"ctor": "Cons",
|
|
"args": [
|
|
{ "t": "lit", "lit": { "kind": "int", "value": 3 } },
|
|
{
|
|
"t": "ctor",
|
|
"type": "IntList",
|
|
"ctor": "Cons",
|
|
"args": [
|
|
{ "t": "lit", "lit": { "kind": "int", "value": 1 } },
|
|
{
|
|
"t": "ctor",
|
|
"type": "IntList",
|
|
"ctor": "Cons",
|
|
"args": [
|
|
{ "t": "lit", "lit": { "kind": "int", "value": 4 } },
|
|
{
|
|
"t": "ctor",
|
|
"type": "IntList",
|
|
"ctor": "Cons",
|
|
"args": [
|
|
{ "t": "lit", "lit": { "kind": "int", "value": 1 } },
|
|
{
|
|
"t": "ctor",
|
|
"type": "IntList",
|
|
"ctor": "Cons",
|
|
"args": [
|
|
{ "t": "lit", "lit": { "kind": "int", "value": 5 } },
|
|
{
|
|
"t": "ctor",
|
|
"type": "IntList",
|
|
"ctor": "Cons",
|
|
"args": [
|
|
{ "t": "lit", "lit": { "kind": "int", "value": 9 } },
|
|
{
|
|
"t": "ctor",
|
|
"type": "IntList",
|
|
"ctor": "Cons",
|
|
"args": [
|
|
{ "t": "lit", "lit": { "kind": "int", "value": 2 } },
|
|
{
|
|
"t": "ctor",
|
|
"type": "IntList",
|
|
"ctor": "Cons",
|
|
"args": [
|
|
{ "t": "lit", "lit": { "kind": "int", "value": 6 } },
|
|
{
|
|
"t": "ctor",
|
|
"type": "IntList",
|
|
"ctor": "Cons",
|
|
"args": [
|
|
{ "t": "lit", "lit": { "kind": "int", "value": 5 } },
|
|
{
|
|
"t": "ctor",
|
|
"type": "IntList",
|
|
"ctor": "Cons",
|
|
"args": [
|
|
{ "t": "lit", "lit": { "kind": "int", "value": 3 } },
|
|
{
|
|
"t": "ctor",
|
|
"type": "IntList",
|
|
"ctor": "Cons",
|
|
"args": [
|
|
{ "t": "lit", "lit": { "kind": "int", "value": 5 } },
|
|
{
|
|
"t": "ctor",
|
|
"type": "IntList",
|
|
"ctor": "Nil",
|
|
"args": []
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
"body": {
|
|
"t": "app",
|
|
"fn": { "t": "var", "name": "print_list" },
|
|
"args": [
|
|
{
|
|
"t": "app",
|
|
"fn": { "t": "var", "name": "sort" },
|
|
"args": [{ "t": "var", "name": "xs" }]
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|