Skip to content

Commit 66f27f1

Browse files
committed
docs: reconcile rule 8 with the System::Linq surface, and correct a claim the header could not support
Both queues empty, so this turn audited the mechanically checkable rules in CLAUDE.md. Three came back clean and one exposed an apparent contradiction. CLEAN: rule 4 (SPDX) -- 1,273 production files, 0 missing. Rule 6 (C++17 nested namespace form) -- 0 old-form sites. And the porting checklist's "no bare NotImplementedException stub" -- 6 production throw sites, every one carrying an explanatory comment. (A looser first count said 9; the extra three are doc-comments saying @throws, not code.) THE CONTRADICTION: rule 8 read "No LINQ. Use std::ranges in ported code instead", unqualified -- while modules/core/include/System/Linq.hpp is a 508-line System::Linq with Where, Select, FirstOrDefault and ~17 more. Read alone, the rule says the tree violates it. It does not: the rule governs code THIS project writes, and the header is a compatibility surface for ported C#/XNA call sites. That reconciliation existed only in the header, so it is now in CLAUDE.md too, where it is loaded every session. AND THE HEADER'S OWN JUSTIFICATION WAS TOO STRONG. It said the class "exists only to support already-ported C#/XNA call sites that use these operators", which implies such sites exist. Measured with a strict search for `System::Linq::`: ZERO uses in this repository's production code, ZERO in cna, ZERO in mobile-eggbert. Its only users are its own two test files. A first, looser grep suggested four production sites; all four were Xml::Linq, a different namespace. So it is a capability offered IN ADVANCE of a caller rather than a response to one. Both the header and rule 8 now say that, and both record that removing it would be a public-surface decision rather than a cleanup -- which is why this change corrects the wording and touches no code. Comment and documentation only; the full build is clean and the gate is unaffected at 17,585.
1 parent 67ae1dd commit 66f27f1

2 files changed

Lines changed: 28 additions & 4 deletions

File tree

CLAUDE.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,16 @@
1818
parameterized-property case, applied across every indexer in the codebase.
1919
6. **Namespace syntax:** `namespace System::Collections::Generic {` (C++17 nested form).
2020
7. **Use `SharpRuntime::intcs`, not `int`** in public APIs that mirror .NET `int` parameters.
21-
8. **No LINQ.** Use `std::ranges` in ported code instead.
21+
8. **No LINQ** in the code this project writes — use `std::ranges` in ported bodies instead.
22+
**This does not mean the tree contains no LINQ surface, and the distinction is worth stating
23+
here because the two look like a contradiction otherwise**: `modules/core/include/System/Linq.hpp`
24+
is a 508-line `System::Linq` providing `Where`, `Select`, `FirstOrDefault` and ~17 more over
25+
`std::vector<T>`. It exists as a **compatibility surface for ported C#/XNA call sites**, not as
26+
a licence to use those operators in new code. Measured 2026-08-19: a strict search for
27+
`System::Linq::` finds **zero** uses in this repository's production code, **zero** in `cna` and
28+
**zero** in `mobile-eggbert` — its only users are its own two test files. So it is a capability
29+
offered *in advance* of a caller; removing it would be a public-surface decision rather than a
30+
cleanup.
2231
9. **No merge to master or tags** without explicit per-action user approval.
2332
10. **No broad header refactor** — naming conventions touch 449+ files and would break CNA.
2433
11. **Copy doc-comments from .NET source** — when porting a type, if the `.NET` source (`/rv/tmp/runtime/src/libraries/`) has XML doc comments and the sharp-runtime header has none, copy them as Doxygen `/** */` comments where the meaning translates cleanly to C++.

modules/core/include/System/Linq.hpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,24 @@ namespace System::Linq {
3131
* Concat, Contains. Not implemented (real .NET's Enumerable surface is 100+ methods):
3232
* GroupBy, Join, Zip, SelectMany, ToDictionary, ToHashSet, Average, Aggregate, ElementAt,
3333
* SkipWhile, TakeWhile, Except, Intersect, Union, SequenceEqual, Single/SingleOrDefault,
34-
* DefaultIfEmpty, Chunk, and more -- add on demand as ported code needs them, per
35-
* CLAUDE.md's "No LINQ" policy for code THIS project writes (this class exists only to
36-
* support already-ported C#/XNA call sites that use these operators).
34+
* DefaultIfEmpty, Chunk, and more -- add on demand as ported code needs them.
35+
*
36+
* @note **How this squares with CLAUDE.md rule 8, "No LINQ".** That rule governs the code
37+
* THIS project writes: ported bodies use `std::ranges`, not these operators. This header is
38+
* the other side of it -- a compatibility surface for ported C#/XNA call sites that already
39+
* spell `Where`/`Select`/`FirstOrDefault`.
40+
*
41+
* @note **Measured 2026-08-19, because the previous wording claimed more than is true.** It
42+
* said this "exists only to support already-ported C#/XNA call sites that use these
43+
* operators", which implies such sites exist. They do not, anywhere: a strict search for
44+
* `System::Linq::` finds **zero** uses in this repository's production code, **zero** in
45+
* `cna` and **zero** in `mobile-eggbert`. Its only users are its own two test files
46+
* (`LinqTests.cpp` and `ComparisonContractTests.cpp`).
47+
*
48+
* So this is a capability offered **in advance** of a caller rather than a response to one.
49+
* That is a deliberate position and not a defect -- the surface is what lets a future port
50+
* land without first re-litigating rule 8 -- but it should be read as such, and its removal
51+
* would be a public-surface decision rather than a cleanup.
3752
*
3853
* @note Status: PARTIAL
3954
*/

0 commit comments

Comments
 (0)