You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
unreferenced_by_name reads 0.25/file for haskell and scheme: a module export list and a type signature are declarations, not references #2823
unreferenced_by_name (the census #2806 renamed from orphaned_logic) reads 0.25 per file for haskell and scheme against a 2.50 corpus median — 12 of each language's 13 probe functions read as referenced when nothing calls any of them. This is #2806's defect with the sign flipped: there the census counted a function as unreferenced that the language reaches without naming it; here it counts a function as referenced on a name occurrence that is a declaration, not a reference.
Measured 2026-09-06 on engine fix/2806-orphan-invocation-model (branched from main 87cfc933) / corpus main 5cf94e7, per-file census over keyword-rosetta/data.
The two forms
_is_orphan (detector.py) counts occurrences of the name outside [start_idx, end_idx), discounts one of them when the span contains none (the declaration, which for several slicer modes falls outside its own span), and discounts the offsets captured by the registry's _visibility_export rule (#2774). That budget of one implicit + one declared form is exactly enough for tcl/shell/ruby/powershell/assembly. haskell and scheme each write the name a third time:
moduleA (probeGlobals, probeTest, probeSafety) where-- export list: one occurrence per nameprobeGlobals::Int->Int-- type signature: another
probeGlobals env = env -- the equation (span starts after the name)
(export probe-globals) ;; scheme declares no _visibility_export, so this reads as a use
(define (probe-globals env) env)
haskell cannot be expressed with the mechanism as it stands. export_name_starts is built as frozenset(m.start(1) for m in _vis_export.finditer(...)) — one capture group, one name per match — and a Haskell module export list holds an arbitrary number of names inside one pair of parens. Declaring the type signature instead (^([a-z]\w*)[ \t]*::) is a legal single-capture rule but does not move the count (measured: still 0.25), because the export list alone is enough to clear every flag.
So the fix is (1) let _visibility_export yield more than one name per match — every group, or a second _visibility_export_list whose capture is the whole list and whose names are split by the engine — and (2) declare it for haskell and scheme, and (3) plant the missing dispatch calls in keyword-rosetta/data/{haskell,scheme}/main.* in the same wave.
Why it matters
The metric feeds risk_tech_debt and the orphan→api conversion, so an under-reading language looks maximally clean on both. It is also the last shape of the census that is still measurement rather than code: after #2806, orphan-detection-is-name-recurrence's remaining languages are these two plus the no-functions family (html, markdown, yaml, sqlite, dockerfile, css), which is a different question (#2549's undefined family).
unreferenced_by_name(the census #2806 renamed fromorphaned_logic) reads 0.25 per file for haskell and scheme against a 2.50 corpus median — 12 of each language's 13 probe functions read as referenced when nothing calls any of them. This is #2806's defect with the sign flipped: there the census counted a function as unreferenced that the language reaches without naming it; here it counts a function as referenced on a name occurrence that is a declaration, not a reference.Measured 2026-09-06 on engine
fix/2806-orphan-invocation-model(branched from main87cfc933) / corpus main5cf94e7, per-file census overkeyword-rosetta/data.The two forms
_is_orphan(detector.py) counts occurrences of the name outside[start_idx, end_idx), discounts one of them when the span contains none (the declaration, which for several slicer modes falls outside its own span), and discounts the offsets captured by the registry's_visibility_exportrule (#2774). That budget of one implicit + one declared form is exactly enough for tcl/shell/ruby/powershell/assembly. haskell and scheme each write the name a third time:What is and is not enough
_visibility_exportdeclaration it never got. Adding^\([ \t]*export[ \t]+([a-zA-Z][\w\-!?*/<>=+]*)moves the corpus 0.25 → 3.00 per file, not 2.50 — becausemain.scm'sentrydoes not call its probes either, so scheme also carries the corpus plant gap orphaned_logic reports 100% dead code for five languages whose invocation model never names the callee — the family #2727 closed without covering #2806 found in abap/m4/makefile/objective-c, hidden until now behind the export false-negative. Both halves have to land together or scheme swaps an amber cell for a worse one.export_name_startsis built asfrozenset(m.start(1) for m in _vis_export.finditer(...))— one capture group, one name per match — and a Haskell module export list holds an arbitrary number of names inside one pair of parens. Declaring the type signature instead (^([a-z]\w*)[ \t]*::) is a legal single-capture rule but does not move the count (measured: still 0.25), because the export list alone is enough to clear every flag.So the fix is (1) let
_visibility_exportyield more than one name per match — every group, or a second_visibility_export_listwhose capture is the whole list and whose names are split by the engine — and (2) declare it for haskell and scheme, and (3) plant the missing dispatch calls inkeyword-rosetta/data/{haskell,scheme}/main.*in the same wave.Why it matters
The metric feeds
risk_tech_debtand the orphan→api conversion, so an under-reading language looks maximally clean on both. It is also the last shape of the census that is still measurement rather than code: after #2806,orphan-detection-is-name-recurrence's remaining languages are these two plus the no-functions family (html, markdown, yaml, sqlite, dockerfile, css), which is a different question (#2549's undefined family).Part of #2812. Successor to #2774 and the sign-flip of #2806; related #2727, #2754.