// Feature 1 — materialize a tuple from a pack via `(..xs.method)` (Decision 2:
// a pack is stored by materializing a tuple). `(..xs.get)` projects `get` over
// the pack and collects the results into a real tuple value, which can then be
// stored, indexed, and (for `Box(T)`) is heterogeneous per position.

#import "modules/std.sx";

Box :: protocol(T: Type) {
    get :: () -> T;
}
IntCell :: struct { v: s64; }
StrCell :: struct { s: string; }
impl Box(s64) for IntCell { get :: (self: *IntCell) -> s64 => self.v; }
impl Box(string) for StrCell { get :: (self: *StrCell) -> string => self.s; }

snapshot :: (..xs: Box) -> void {
    t := (..xs.get);                 // tuple (s64, string) materialized from the pack
    print("0={} 1={}\n", t.0, t.1);
}

main :: () -> s32 {
    snapshot(IntCell.{ v = 42 }, StrCell.{ s = "hi" });
    snapshot(StrCell.{ s = "x" }, IntCell.{ v = 7 });   // order swapped → (string, s64)
    0;
}
