iter 24.2: class Show + 4 primitive instances + 22b TShow migration

Ships class Show a where show : (a borrow) -> Str in the prelude
plus primitive Show Int / Bool / Str / Float instances. Each
instance body is a single-application lambda invoking the
corresponding runtime primitive (int_to_str, bool_to_str,
str_clone, float_to_str) — first prelude instance bodies to call
runtime primitives directly. Float is included in Show (unlike
Eq/Ord) because textual representation is well-defined modulo the
NaN-spelling caveat at DESIGN.md §Float semantics.

The 22b typeclass test corpus is migrated preemptively: 21 fixture
files and 6 consumer files (typeclass_22b{2,3}.rs +
hash.rs ct4 pin + workspace.rs iter22b1 tests + the
instance_present.prose.txt snapshot) rename class Show / show
to class TShow / tshow, analogous to the existing TEq/TOrd
convention. Migration runs before the prelude additions so the
workspace stays green throughout.

Three new tests pin the post-mono shape: show_mono_synthesis.rs
(existence of show__Int/Bool/Str/Float as Def::Fn entries in the
prelude post-mono module), show_dispatch_pin.rs (bare show and
tshow both Step-2 singletons workspace-globally),
mono_hash_stability.rs::primitive_show_mono_symbol_hashes_stay_bit_identical
(body hashes pinned for the 4 new mono symbols).

DESIGN.md §Prelude (built-in) classes drops Show from the
deferred-features list and appends a milestone-24 paragraph
naming the class signature + the 4 instances + the body shape.
print rewire stays deferred to iter 24.3.

Tests: 552 passed (was 548 + 4 new). bench/compile_check +
bench/cross_lang exit 0. bench/check exits 1 on the recurring
noise envelope per the conservative-call lineage.
This commit is contained in:
2026-05-13 03:31:40 +02:00
parent 64cea0ef41
commit 3286117605
34 changed files with 703 additions and 169 deletions
+102
View File
@@ -219,6 +219,108 @@
}
]
},
{
"kind": "class",
"name": "Show",
"param": "a",
"doc": "Producer of a human-readable Str representation. Ships in milestone 24 with primitive instances for Int/Bool/Str/Float; user types declare their own instance.",
"methods": [
{
"name": "show",
"type": {
"k": "fn",
"params": [{ "k": "var", "name": "a" }],
"param_modes": ["borrow"],
"ret": { "k": "con", "name": "Str" },
"effects": []
}
}
]
},
{
"kind": "instance",
"class": "Show",
"type": { "k": "con", "name": "Int" },
"methods": [
{
"name": "show",
"body": {
"t": "lam",
"params": ["x"],
"paramTypes": [{ "k": "con", "name": "Int" }],
"retType": { "k": "con", "name": "Str" },
"body": {
"t": "app",
"fn": { "t": "var", "name": "int_to_str" },
"args": [{ "t": "var", "name": "x" }]
}
}
}
]
},
{
"kind": "instance",
"class": "Show",
"type": { "k": "con", "name": "Bool" },
"methods": [
{
"name": "show",
"body": {
"t": "lam",
"params": ["x"],
"paramTypes": [{ "k": "con", "name": "Bool" }],
"retType": { "k": "con", "name": "Str" },
"body": {
"t": "app",
"fn": { "t": "var", "name": "bool_to_str" },
"args": [{ "t": "var", "name": "x" }]
}
}
}
]
},
{
"kind": "instance",
"class": "Show",
"type": { "k": "con", "name": "Str" },
"methods": [
{
"name": "show",
"body": {
"t": "lam",
"params": ["x"],
"paramTypes": [{ "k": "con", "name": "Str" }],
"retType": { "k": "con", "name": "Str" },
"body": {
"t": "app",
"fn": { "t": "var", "name": "str_clone" },
"args": [{ "t": "var", "name": "x" }]
}
}
}
]
},
{
"kind": "instance",
"class": "Show",
"type": { "k": "con", "name": "Float" },
"methods": [
{
"name": "show",
"body": {
"t": "lam",
"params": ["x"],
"paramTypes": [{ "k": "con", "name": "Float" }],
"retType": { "k": "con", "name": "Str" },
"body": {
"t": "app",
"fn": { "t": "var", "name": "float_to_str" },
"args": [{ "t": "var", "name": "x" }]
}
}
}
]
},
{
"kind": "fn",
"name": "ne",
+49
View File
@@ -0,0 +1,49 @@
{
"schema": "ailang/v0",
"name": "show_mono_pin_smoke",
"imports": [],
"defs": [
{
"kind": "fn",
"name": "main",
"type": {
"k": "fn",
"params": [],
"ret": { "k": "con", "name": "Unit" },
"effects": ["IO"]
},
"params": [],
"body": {
"t": "let",
"name": "s1",
"value": { "t": "app",
"fn": { "t": "var", "name": "show" },
"args": [{ "t": "lit", "lit": { "kind": "int", "value": 42 } }] },
"body": {
"t": "let",
"name": "s2",
"value": { "t": "app",
"fn": { "t": "var", "name": "show" },
"args": [{ "t": "lit", "lit": { "kind": "bool", "value": true } }] },
"body": {
"t": "let",
"name": "s3",
"value": { "t": "app",
"fn": { "t": "var", "name": "show" },
"args": [{ "t": "lit", "lit": { "kind": "str", "value": "x" } }] },
"body": {
"t": "let",
"name": "s4",
"value": { "t": "app",
"fn": { "t": "var", "name": "show" },
"args": [{ "t": "lit", "lit": { "kind": "float", "bits": "3ff8000000000000" } }] },
"body": { "t": "do",
"op": "io/print_str",
"args": [{ "t": "var", "name": "s1" }] }
}
}
}
}
}
]
}
+2 -2
View File
@@ -12,14 +12,14 @@
"defs": [
{
"kind": "instance",
"class": "test_22b1_dup_classmod.Show",
"class": "test_22b1_dup_classmod.TShow",
"type": {
"k": "con",
"name": "test_22b1_dup_b.MyInt"
},
"methods": [
{
"name": "show",
"name": "tshow",
"body": {
"t": "lit",
"lit": {
+2 -2
View File
@@ -17,11 +17,11 @@
},
{
"kind": "instance",
"class": "test_22b1_dup_classmod.Show",
"class": "test_22b1_dup_classmod.TShow",
"type": { "k": "con", "name": "MyInt" },
"methods": [
{
"name": "show",
"name": "tshow",
"body": { "t": "lit", "lit": { "kind": "str", "value": "from-b" } }
}
]
+2 -2
View File
@@ -5,11 +5,11 @@
"defs": [
{
"kind": "class",
"name": "Show",
"name": "TShow",
"param": "a",
"methods": [
{
"name": "show",
"name": "tshow",
"type": {
"k": "fn",
"params": [{ "k": "var", "name": "a" }],
+6 -6
View File
@@ -5,11 +5,11 @@
"defs": [
{
"kind": "class",
"name": "Show",
"name": "TShow",
"param": "a",
"methods": [
{
"name": "show",
"name": "tshow",
"type": {
"k": "fn",
"params": [{ "k": "var", "name": "a" }],
@@ -21,22 +21,22 @@
},
{
"kind": "instance",
"class": "Show",
"class": "TShow",
"type": { "k": "con", "name": "Int" },
"methods": [
{
"name": "show",
"name": "tshow",
"body": { "t": "lit", "lit": { "kind": "str", "value": "first" } }
}
]
},
{
"kind": "instance",
"class": "Show",
"class": "TShow",
"type": { "k": "con", "name": "Int" },
"methods": [
{
"name": "show",
"name": "tshow",
"body": { "t": "lit", "lit": { "kind": "str", "value": "second" } }
}
]
+4 -4
View File
@@ -5,11 +5,11 @@
"defs": [
{
"kind": "class",
"name": "Show",
"name": "TShow",
"param": "a",
"methods": [
{
"name": "show",
"name": "tshow",
"type": {
"k": "fn",
"params": [{ "k": "var", "name": "a" }],
@@ -21,11 +21,11 @@
},
{
"kind": "instance",
"class": "Show",
"class": "TShow",
"type": { "k": "con", "name": "Int" },
"methods": [
{
"name": "show",
"name": "tshow",
"body": { "t": "lit", "lit": { "kind": "str", "value": "<int>" } }
}
]
+2 -2
View File
@@ -7,11 +7,11 @@
"defs": [
{
"kind": "instance",
"class": "test_22b1_orphan_third_classmod.Show",
"class": "test_22b1_orphan_third_classmod.TShow",
"type": { "k": "con", "name": "Int" },
"methods": [
{
"name": "show",
"name": "tshow",
"body": { "t": "lit", "lit": { "kind": "str", "value": "<int>" } }
}
]
@@ -5,11 +5,11 @@
"defs": [
{
"kind": "class",
"name": "Show",
"name": "TShow",
"param": "a",
"methods": [
{
"name": "show",
"name": "tshow",
"type": {
"k": "fn",
"params": [{ "k": "var", "name": "a" }],
@@ -5,11 +5,11 @@
"defs": [
{
"kind": "class",
"name": "Show",
"name": "TShow",
"param": "a",
"methods": [
{
"name": "show",
"name": "tshow",
"type": {
"k": "fn",
"params": [{ "k": "var", "name": "a" }],
@@ -21,11 +21,11 @@
},
{
"kind": "instance",
"class": "Show",
"class": "TShow",
"type": { "k": "con", "name": "Int" },
"methods": [
{
"name": "show",
"name": "tshow",
"body": { "t": "lit", "lit": { "kind": "str", "value": "n" } }
}
]
@@ -5,11 +5,11 @@
"defs": [
{
"kind": "class",
"name": "Show",
"name": "TShow",
"param": "a",
"methods": [
{
"name": "show",
"name": "tshow",
"type": {
"k": "fn",
"params": [{ "k": "var", "name": "a" }],
@@ -26,7 +26,7 @@
"k": "forall",
"vars": ["a"],
"constraints": [
{ "class": "Show", "type": { "k": "var", "name": "a" } }
{ "class": "TShow", "type": { "k": "var", "name": "a" } }
],
"body": {
"k": "fn",
@@ -38,7 +38,7 @@
"params": ["x"],
"body": {
"t": "app",
"fn": { "t": "var", "name": "show" },
"fn": { "t": "var", "name": "tshow" },
"args": [{ "t": "var", "name": "x" }]
}
}
+5 -5
View File
@@ -4,9 +4,9 @@
"imports": [],
"defs": [
{
"kind": "class", "name": "Show", "param": "a",
"kind": "class", "name": "TShow", "param": "a",
"methods": [{
"name": "show",
"name": "tshow",
"type": {
"k": "fn", "params": [{ "k": "var", "name": "a" }],
"ret": { "k": "con", "name": "Str" }, "effects": []
@@ -15,10 +15,10 @@
},
{
"kind": "instance",
"class": "Show",
"class": "TShow",
"type": { "k": "con", "name": "Int" },
"methods": [{
"name": "show",
"name": "tshow",
"body": {
"t": "lam",
"params": ["x"],
@@ -38,7 +38,7 @@
"params": [],
"body": {
"t": "app",
"fn": { "t": "var", "name": "show" },
"fn": { "t": "var", "name": "tshow" },
"args": [{ "t": "lit", "lit": { "kind": "int", "value": 42 } }]
}
}
@@ -1,11 +1,11 @@
// module test_22b2_instance_present
class Show a {
fn show(x: a) -> Str
class TShow a {
fn tshow(x: a) -> Str
}
instance Show Int {
fn show {
instance TShow Int {
fn tshow {
|x: a| -> Str {
"n"
}
@@ -13,5 +13,5 @@ instance Show Int {
}
fn main() -> Str {
show(42)
tshow(42)
}
@@ -5,11 +5,11 @@
"defs": [
{
"kind": "class",
"name": "Show",
"name": "TShow",
"param": "a",
"methods": [
{
"name": "show",
"name": "tshow",
"type": {
"k": "fn",
"params": [{ "k": "var", "name": "a" }],
@@ -35,7 +35,7 @@
"params": ["x"],
"body": {
"t": "app",
"fn": { "t": "var", "name": "show" },
"fn": { "t": "var", "name": "tshow" },
"args": [{ "t": "var", "name": "x" }]
}
}
+3 -3
View File
@@ -5,11 +5,11 @@
"defs": [
{
"kind": "class",
"name": "Show",
"name": "TShow",
"param": "a",
"methods": [
{
"name": "show",
"name": "tshow",
"type": {
"k": "fn",
"params": [{ "k": "var", "name": "a" }],
@@ -31,7 +31,7 @@
"params": [],
"body": {
"t": "app",
"fn": { "t": "var", "name": "show" },
"fn": { "t": "var", "name": "tshow" },
"args": [{ "t": "lit", "lit": { "kind": "int", "value": 42 } }]
}
}
@@ -5,11 +5,11 @@
"defs": [
{
"kind": "class",
"name": "Show",
"name": "TShow",
"param": "a",
"methods": [
{
"name": "show",
"name": "tshow",
"type": {
"k": "fn",
"params": [{ "k": "var", "name": "a" }],
@@ -35,7 +35,7 @@
"params": ["x"],
"body": {
"t": "app",
"fn": { "t": "var", "name": "show" },
"fn": { "t": "var", "name": "tshow" },
"args": [{ "t": "var", "name": "x" }]
}
},
@@ -55,7 +55,7 @@
"params": ["y"],
"body": {
"t": "app",
"fn": { "t": "var", "name": "show" },
"fn": { "t": "var", "name": "tshow" },
"args": [{ "t": "var", "name": "y" }]
}
}
+4 -4
View File
@@ -5,11 +5,11 @@
"defs": [
{
"kind": "class",
"name": "Show",
"name": "TShow",
"param": "a",
"methods": [
{
"name": "show",
"name": "tshow",
"type": {
"k": "fn",
"params": [{ "k": "var", "name": "a" }],
@@ -21,11 +21,11 @@
},
{
"kind": "instance",
"class": "Show",
"class": "TShow",
"type": { "k": "con", "name": "Int" },
"methods": [
{
"name": "show",
"name": "tshow",
"body": {
"t": "lam",
"params": ["x"],
@@ -5,11 +5,11 @@
"defs": [
{
"kind": "class",
"name": "Show",
"name": "TShow",
"param": "a",
"methods": [
{
"name": "show",
"name": "tshow",
"type": {
"k": "fn",
"params": [{ "k": "var", "name": "a" }],
@@ -15,7 +15,7 @@
"params": [],
"body": {
"t": "app",
"fn": { "t": "var", "name": "show" },
"fn": { "t": "var", "name": "tshow" },
"args": [{ "t": "lit", "lit": { "kind": "int", "value": 42 } }]
}
}
@@ -19,7 +19,7 @@
"params": ["x"],
"body": {
"t": "app",
"fn": { "t": "var", "name": "show" },
"fn": { "t": "var", "name": "tshow" },
"args": [{ "t": "var", "name": "x" }]
}
}
+1 -1
View File
@@ -15,7 +15,7 @@
"params": [],
"body": {
"t": "app",
"fn": { "t": "var", "name": "show" },
"fn": { "t": "var", "name": "tshow" },
"args": [{ "t": "lit", "lit": { "kind": "int", "value": 42 } }]
}
}
+6 -6
View File
@@ -4,9 +4,9 @@
"imports": [],
"defs": [
{
"kind": "class", "name": "Show", "param": "a",
"kind": "class", "name": "TShow", "param": "a",
"methods": [{
"name": "show",
"name": "tshow",
"type": {
"k": "fn", "params": [{ "k": "var", "name": "a" }],
"ret": { "k": "con", "name": "Str" }, "effects": []
@@ -15,10 +15,10 @@
},
{
"kind": "instance",
"class": "Show",
"class": "TShow",
"type": { "k": "con", "name": "Int" },
"methods": [{
"name": "show",
"name": "tshow",
"body": {
"t": "lam",
"params": ["x"],
@@ -41,12 +41,12 @@
"name": "_a",
"value": {
"t": "app",
"fn": { "t": "var", "name": "show" },
"fn": { "t": "var", "name": "tshow" },
"args": [{ "t": "lit", "lit": { "kind": "int", "value": 5 } }]
},
"body": {
"t": "app",
"fn": { "t": "var", "name": "show" },
"fn": { "t": "var", "name": "tshow" },
"args": [{ "t": "lit", "lit": { "kind": "int", "value": 7 } }]
}
}
+4 -4
View File
@@ -4,9 +4,9 @@
"imports": [],
"defs": [
{
"kind": "class", "name": "Show", "param": "a",
"kind": "class", "name": "TShow", "param": "a",
"methods": [{
"name": "show",
"name": "tshow",
"type": {
"k": "fn", "params": [{ "k": "var", "name": "a" }],
"ret": { "k": "con", "name": "Str" }, "effects": []
@@ -15,10 +15,10 @@
},
{
"kind": "instance",
"class": "Show",
"class": "TShow",
"type": { "k": "con", "name": "Int" },
"methods": [{
"name": "show",
"name": "tshow",
"body": {
"t": "lam",
"params": ["x"],
@@ -4,9 +4,9 @@
"imports": [],
"defs": [
{
"kind": "class", "name": "Show", "param": "a",
"kind": "class", "name": "TShow", "param": "a",
"methods": [{
"name": "show",
"name": "tshow",
"type": {
"k": "fn", "params": [{ "k": "var", "name": "a" }],
"ret": { "k": "con", "name": "Str" }, "effects": []
@@ -25,10 +25,10 @@
},
{
"kind": "instance",
"class": "Show",
"class": "TShow",
"type": { "k": "con", "name": "Int" },
"methods": [{
"name": "show",
"name": "tshow",
"body": {
"t": "lam",
"params": ["x"],
@@ -66,17 +66,17 @@
"name": "_t",
"value": {
"t": "app",
"fn": { "t": "var", "name": "show" },
"fn": { "t": "var", "name": "tshow" },
"args": [{ "t": "lit", "lit": { "kind": "int", "value": 5 } }]
},
"body": {
"t": "let",
"name": "show",
"name": "tshow",
"value": { "t": "lit", "lit": { "kind": "str", "value": "shadow" } },
"body": {
"t": "let",
"name": "_u",
"value": { "t": "var", "name": "show" },
"value": { "t": "var", "name": "tshow" },
"body": {
"t": "app",
"fn": { "t": "var", "name": "foo" },