feat(stdlib): generic Iter_Map/Filter/Fold with func monomorphization

Add Iter_Map<T,U>, Filter, Fold, Any, All, ForEach over fat function
pointers; keep Iter_MapInt and friends as thin aliases.

Compiler fixes required for non-int returns and capturing closures:
- bootstrap: resolve fat-func call return type under mono typeSubst
- bootstrap: type-check args of Foo<T>(...) so closures capture correctly
- selfhost: substitute type params inside tekFunc (BuxFn_U_T → concrete)
- selfhost: emit cstr fat typedefs with #ifndef redefinition guards

Example: examples/iter_generic.bux (int↔String map, fold, closures).
Selfhost-loop remains binary-identical.
This commit is contained in:
2026-07-18 01:07:41 +03:00
parent 26631252c0
commit eac78f28c1
9 changed files with 267 additions and 87 deletions
+20 -6
View File
@@ -48,7 +48,7 @@
| A.2 | String: IsEmpty, ReplaceAll | Чести операции; само first-replace досега | ✅ (тази сесия) |
| A.3 | Os_Exit + Test_AssertEqString / richer asserts | Тестове и CLI без raw `bux_exit` | ✅ (тази сесия) |
| A.4 | Map_Remove / Set polish | Completeness на колекциите | ✅ (тази сесия) |
| A.5 | Iter: map/filter/fold върху closures | Higher-order без boilerplate | ✅ Iter_Map/Filter/FoldInt |
| A.5 | Iter: map/filter/fold върху closures | Higher-order без boilerplate | ✅ generic `Iter_Map`/`Filter`/`Fold` + Int aliases |
| A.6 | Result helpers: Expect, UnwrapErr, Or | По-малко match boilerplate | ✅ (тази сесия) |
### B — Compiler Correctness (P0)
@@ -246,10 +246,24 @@ A (stdlib ergonomics) → B (compiler holes) → C (ownership depth)
---
## Сесия 14 (generic Iter map/filter/fold)
1. **`Iter_Map<T,U>` / `Filter<T>` / `Fold<T,Acc>` / `Any` / `All` / `ForEach`** — fat `func` params + monomorphization
2. **Int aliases** keep working: `Iter_MapInt``Iter_Map<int,int>`, …
3. **Bootstrap fixes:**
- call return type for local fat-func (`f: func(T)->U`) after mono (was always `int` → String map truncated pointers)
- generic call `Foo<T>(…)` now type-checks args (closures get capture analysis)
4. **Selfhost fixes:**
- `Lcx_SubstituteType` recurses into `tekFunc` (was leaving `BuxFn_U_T`)
- fat typedef emit covers cstr shapes + `#ifndef` guards
5. Example: `examples/iter_generic.bux` (int↔String map, filter, fold, closures)
6. Verified: bootstrap + **buxc2** + selfhost-loop IDENTICAL ✓
---
## Следващи стъпки
1. **Generic Iter map** (не само int), ако monomorphization с `func` params е стабилна
2. Struct/tuple patterns (`Point { x, y }`, `(a, b)`) + nested bindings
3. Match arm multi-stmt bodies (beyond single expr)
4. LSP: wire hover types from real sema (replace lightweight index where possible)
1. Struct/tuple patterns (`Point { x, y }`, `(a, b)`) + nested bindings
2. Match arm multi-stmt bodies (beyond single expr)
3. LSP: wire hover types from real sema (replace lightweight index where possible)
4. Generic type inference for `Iter_Map` without explicit `<T,U>`
+9 -8
View File
@@ -143,18 +143,19 @@ struct Iter<T> {
| `Iter_AllEq<T>` | `func Iter_AllEq<T>(it: *Iter<T>, value: T) -> bool` | True if all remaining equal value |
| `Iter_Collect<T>` | `func Iter_Collect<T>(it: *Iter<T>) -> Array<T>` | Collect remaining into a new Array |
### Higher-order (int-specialized)
### Higher-order (generic + int aliases)
Take fat function pointers / closures (`func(int) -> int`, `func(int) -> bool`, …).
Take fat function pointers / closures. Prefer the generic forms; `*Int` aliases remain for compatibility.
| Function | Signature | Description |
|----------|-----------|-------------|
| `Iter_MapInt` | `func Iter_MapInt(it: *Iter<int>, f: func(int) -> int) -> Array<int>` | Map each element |
| `Iter_FilterInt` | `func Iter_FilterInt(it: *Iter<int>, pred: func(int) -> bool) -> Array<int>` | Keep matching elements |
| `Iter_FoldInt` | `func Iter_FoldInt(it: *Iter<int>, init: int, f: func(int, int) -> int) -> int` | Left fold |
| `Iter_ForEachInt` | `func Iter_ForEachInt(it: *Iter<int>, f: func(int) -> int)` | Side-effect per element |
| `Iter_AnyInt` | `func Iter_AnyInt(it: *Iter<int>, pred: func(int) -> bool) -> bool` | Any matches pred |
| `Iter_AllInt` | `func Iter_AllInt(it: *Iter<int>, pred: func(int) -> bool) -> bool` | All match pred |
| `Iter_Map<T,U>` | `func Iter_Map<T,U>(it: *Iter<T>, f: func(T) -> U) -> Array<U>` | Map `T → U` |
| `Iter_Filter<T>` | `func Iter_Filter<T>(it: *Iter<T>, pred: func(T) -> bool) -> Array<T>` | Keep matching |
| `Iter_Fold<T,Acc>` | `func Iter_Fold<T,Acc>(it: *Iter<T>, init: Acc, f: func(Acc, T) -> Acc) -> Acc` | Left fold |
| `Iter_ForEach<T>` | `func Iter_ForEach<T>(it: *Iter<T>, f: func(T) -> int)` | Side-effect per element |
| `Iter_Any<T>` | `func Iter_Any<T>(it: *Iter<T>, pred: func(T) -> bool) -> bool` | Any matches pred |
| `Iter_All<T>` | `func Iter_All<T>(it: *Iter<T>, pred: func(T) -> bool) -> bool` | All match pred |
| `Iter_MapInt` … | wrappers → `Iter_Map<int,int>` etc. | Back-compat |
| `Iter_SumInt` | `func Iter_SumInt(it: *Iter<int>) -> int` | Sum remaining ints |
### Example