Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ Full migration table (when reading older docs that say `var inscope` or `<-` for
| `for (s in A) { B \|> push(s) }` / `push_clone(s)` (iter-var only) | `B \|> push_from(A)` / `push_clone_from(A)` | PERF022: the bulk overload in builtin.das reserves combined capacity up front. Single name `push`/`push_clone` is overloaded between single-element and bulk (ambiguous when destination is `array<T[]>`); the `_from` suffix names the bulk intent. Source must be `array<T>` or C-array — range/iterator sources are not flagged. `emplace` is out of scope (const iter-var can't be moved) |
| `var a : array<T>; for (x in SRC) { if (COND) { a \|> push(EXPR) } }` (or `table<K;V>` + `insert`/`a[k]=v`) | `var a <- [for (x in SRC); EXPR; where COND]` (or `\{for (...); k => v; where ...\}`) | STYLE027: var with empty default-init followed by a for-loop that only push/insert into it. Accepts depth ≤ 2 nested fors and if-filters at any depth. `emplace` excluded — move-source-zeroing differs from comprehension element-construction. Iterator-comprehension form (`[$f ...]`) NOT suggested |
| `var X = clone_expression(E); ... $e(X) ...` (only-uses-are-qmacro-splice) | drop the pre-clone, inline `$e(E)` at each splice site | PERF023: `qmacro`/`qmacro_block`/`qmacro_expr`/`qmacro_block_to_array` go through `apply_template` (templates_boost.das:251), which calls `clone_expression` on every substitution input. Pre-cloning is wasted work. Detection: post-expansion `$e(X)` becomes `add_ptr_ref(X)` inside an `ExprMakeBlock`; visitor tracks splice-wrapper depth via preVisitExprCall/visitExprCall counter on `add_ptr_ref`, classifies each candidate `ExprVar` reference as "safe" when depth>0. Fires only when ALL uses are safe AND ≥1 is observed. Multi-clone-of-same-source flagged too — apply_template clones each substitution independently |
| hand-rolled `is X` / `as X` / null-guard / `ExprRef2Value`-peel ladders in macro code | `qmatch(e, $e(a) + $e(b))` for source-syntax shapes; `match (e) { if (ExprField(name = "key", value = ExprVar(...))) { ... } }` for node-class shapes | both matchers peel `ExprRef2Value` automatically; `\|\|` alternation, `&&` guards, and `match_expr(local)` cover most ladders. Limits + the qmatch↔match division of labor: `skills/das_macros.md` "`match` (daslib/match)" |

For path/filename ops use `fio` helpers (`base_name`/`dir_name`/`path_join`/etc.) — see `skills/filesystem.md`. Never hand-roll `rfind("/")` / slice — misses Windows separators.

Expand Down
16 changes: 15 additions & 1 deletion benchmarks/sql/LINQ_TO_TABLE.md
Original file line number Diff line number Diff line change
Expand Up @@ -243,13 +243,27 @@ PR1 findings:

End of arc: `skills/linq.md` + linq docs mention the table source.

## Late stage (planned) — reducer shapes & general code hygiene
## Late stage (IN PROGRESS, 2026-06-11) — reducer shapes & general code hygiene

Cross-source cleanups; none are table-specific. Items 1–2 are user-facing reducer-shape fixes,
items 3–4 are codebase hygiene investigations (the linq_fold surface is workable but "a tad too
unwieldy" — the table adapter took several stages, and many fuses read as "add this hook, because
reasons" rather than falling out of the architecture).

Status: **items 1+2 DONE** (selector overloads `sum/min/max/average(src, selector)`, the
`_select`-macro bucket-element type stamping, the 2-arg recognizer arm with identity
canonicalization — branch `bbatkin/linq-reducer-shapes`). **Item 4 partially DONE** (4A
upstream-join validation dedup + 4B `loop_source_expr`/`loop_source_name` recontract — branch
`bbatkin/linq-adapter-hygiene`; reverse hooks kept as-is per audit, stringly-Captures →
typed ChainView deferred, per-source dispatch can't become a registry — macro modules compile
into separate contexts). **Item 3 DONE with scope notes** (key-probe matchers + `join_keyb_is_bare_key`
converted to `daslib/match` class patterns — n.b. the AST conversions use BOTH `daslib/ast_match`
(qmatch) and `daslib/match`, each where it fits; prereq landed = ExprRef2Value transparency in
match.das. Declined: `is_bucket_reducer_call` (statement-shaped match doesn't fit a
tuple-returning recognizer) and `extract_decs_bridge` (match.das array patterns reject
das-vector scrutinees — revisit if the library grows them). Toolbox doc:
`skills/das_macros.md` "`match` (daslib/match)".

1. **Identity-lambda reducers**: `_._1 |> max($(v) => v)` (also `min`/`sum`/`average`) fails with
30303 today — the untyped lambda can't infer on the tier-2 lazy-bucket surface, and
`recognize_reducer_specs` has no identity arm either. Fix both ends: recognize the identity
Expand Down
Loading
Loading