← board

What is the syntax for "the C declaration of this name"?

Escalated from [[docs-cross-language-qualifier-note-is-wrong]] (A, p50), which is otherwise ready. The bug is measured and not in doubt; what is missing is a language-design call, and it reserves a name or changes what uses binds either way. Both are yours.

The gap in one line

devdocs/dev/name-resolution.md §2.4 rests on "qualification is the escape and always works". For a Pascal unit it does: pu.Cube reaches the shadowed routine. For uses './mymath.c' there is no qualifier at all — mymath.cube is undefined variable (mymath), so once a Pascal Cube is in scope the C cube is unreachable with no phrase that asks for it.

This is not cosmetic. Own-language-first is safe because qualification is the escape; and [[feature-a-own-language-first-symbol-resolution]]'s acceptance test — renaming the ten __crtl_* functions back to their plain names — recreates exactly this collision on purpose. So the escape has to exist before that lands.

The options, as the bug ticket frames them

1. Bind the file basename as a scope. uses './mymath.c' makes mymath a qualifier, exactly like a Pascal unit name.

2. A reserved language tag — C.cube, and later Zig., Rust., Py..

3. Accept it; require renaming in the C source. Status quo. This is what the ten __crtl_* #defines are, and the standing plan is to DELETE them — so choosing this un-picks that plan and should be recorded as such.

Recommendation

2, with 1 as a later addition rather than an alternative. They answer different questions — "which language" and "which file" — and a codebase that grows a second C file with a clashing name will want both. Starting with the language tag settles the case the own-language-first rule actually depends on, without waiting for the basename-collision bug to be fixed first.

The part that is genuinely yours: whether a bare C in qualifier position is a price worth paying, given that C is a perfectly ordinary variable name in this repo today. A less collision-prone spelling (@C.cube, lang.C.cube) trades readability for safety, and which side of that trade you want is not something the code can tell me.

Either way, [[decide-own-language-first-vs-explicit-import-in-a-case-insensitive-language]] needs its "qualification always works" claim amended, and docs/language/name-resolution.md has the gap under Current status waiting to be replaced by whatever this resolves to.

DECIDED 2026-08-16 (user) — none of the three. uses .. as .., which already ships

No new syntax. Not C.cube, not a sigil, not a reserved scope, and not "rename it in the C source". The escape is the alias clause the dialect already has:

uses './mymath.c' as cmath;
...
WriteLn(Cube(3));        { 27   — Pascal's own }
WriteLn(cmath.cube(3));  { 1027 — C's          }

The user's reasoning, and it is the whole decision: "as soon as we have uses .. as .., this problem is trivially solved without ambiguity" — and [[feature-uses-alias-as]] landed 2026-06-30. It was already solved when this ticket was filed; nobody checked.

Measured on pinned before deciding, all four shapes

form result
Pascal uses './mymath.c' as cmath; -> cmath.cube(3) 1027 — works
NilPy import mymath as cmath -> cmath.cube(3) 1027 — works
NilPy import mymath -> mymath.cube(3) 1027 — bare name binds, as CPython
Pascal uses './mymath.c'; -> mymath.cube(3) undefined variable (mymath)

That last row is the only thing the originating bug ever measured, which is how "there is no qualifier at all" got written down next to a working one.

feature-uses-alias-as maps the alias to the real unit's Strs[] index rather than registering a new compiled unit, which is exactly why it reaches foreign symbols too — the alias is not a namespace of its own, it is a second name for the one the C file's symbols are already tagged with.

Sub-fork, also decided: bare uses './x.c' stays UNBOUND

It will not bind mymath as a scope. The user: "the full name is mymath.c and the extra dot would confuse us — this is exactly why the ..as.. use case was intended." Two independent reasons to keep it that way:

The asymmetry with NilPy is not a defect: Python's import binds a name by definition, Pascal's uses never has. Each follows its own language's rule.

Scope, narrowed deliberately — do not reopen

The qualifier belongs to the importing language, and C's own frontend stays clean. C is the lingua franca — the way languages reach each other's compiled libraries — so the traffic across that boundary is not symmetric in effort: C can import Pascal and Python today, but with far more restriction, because the advanced typing (strings, variants, objects) is not trivially solved in that direction. Pascal and Python importing C is the common case and the one that carries the collision-handling machinery; going the other way, a small wrapper covers it, and rich applications are not written in C here.

Consequences of that, stated so they are choices rather than omissions:

What this changes elsewhere