Skip to content

ada: a single typed parameter counts as 3 args — the comma-free whitespace-split fallback splits 'Env : Integer' into three tokens #2692

Description

@squid-protocol

Found while working #2669 Batch D (#2689's residual shape cells).

What happens

detector.py ~L6169, the per-function argument counter's last resort:

elif stripped and stripped != "()":
    if "," in args_str:
        args_count = self._count_top_level_args(args_str)
    else:
        # Handle space-separated arguments (Lisp/Scheme/Shell)
        args_count = len(args_str.strip().split())

The whitespace split is correct for the languages it names — Scheme's (define (f arg1 arg2) and
shell positionals genuinely separate arguments by spaces. But it is reached by any capture that
is not self-contained and contains no comma, and a single typed parameter is exactly that shape.

Ada's procedure Probe_Globals (Env : Integer) captures Env : Integer, which splits into
["Env", ":", "Integer"]3 arguments for one parameter.

Evidence

Measured on the keyword-rosetta control corpus, where every probe function is planted with exactly
one parameter:

SELECT f.func_name, f.args FROM function_data f JOIN file_data fd ON f.file_id = fd.id
WHERE fd.file_path LIKE 'ada/%';
-- Probe_Globals | 3      <- one parameter, counted as three
-- Probe_Test    | 3
-- ... all 13 identical
-- python's probe_globals | 1   (same planted intent)

Corpus-wide, avg_func_args has a median of 1.0 and ada is the only language above it, at 3.0
(+200%). The other non-1.0 values are accounted for: the 0.825 cluster is the synthetic-bucket
dilution in #2691, and the low outliers are the args-no-parameter-surface-morphology ledger entry.

The general shape

The corpus plants untyped single parameters almost everywhere, so it can only prove the ada case.
The mechanism is not ada-specific — every one of these is a single parameter that the fallback would
score above 1:

capture split count
Env : Integer (ada) 3
const X: Integer (pascal-family) 3
x: number (typescript) 2
x: int (python typed) 2
x: u32 (rust) 2
x int (go) 2

Whether each language actually reaches this branch depends on whether its own args regex produces
a self-contained capture (which routes to _count_top_level_args instead). Ada is confirmed by
measurement; the others are a review question, not a claim.

Note the multi-parameter ada case is worse, not better: X : Integer; Y : Integer has no comma
either — Ada separates parameters with semicolons — so it splits into 6.

Fix shape

Before falling back to a whitespace split, strip type-annotation syntax, or gate the fallback to the
languages it was written for. The safer form is an explicit opt-in flag naming the languages whose
parameters really are space-separated (the same convention _args_arrow_count_groups and the
objective-c colon_selector_groups flag already use here) rather than treating whitespace splitting
as the universal default.

A cheaper interim guard, if the opt-in list is contentious: split on the language's own parameter
separator first (; for ada), then count annotation-bearing segments as one each.

Blast radius

Golden masters move for ada (and any other language the review finds reaching this branch):
args per function, avg_func_args, and cog_raw/structural_mass downstream, since cog_raw
multiplies by sqrt(args + 1). Corpus-side, ada's avg_func_args returns from 3.0 to the planted
1.0, closing a red cell rather than opening one.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugUnintended behavior or logic failure in the enginecore-engineModifications to the central physics and parsing enginemetricsHeuristics, risk exposures, and topological math updates

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions