C is Brittle D is Plastic
H. S. Teoh
hsteoh at qfbox.info
Tue Mar 24 15:41:59 UTC 2026
On Tue, Mar 24, 2026 at 03:25:29PM +0000, user1234 via Digitalmars-d wrote:
> On Tuesday, 24 March 2026 at 14:36:57 UTC, H. S. Teoh wrote:
[...]
> > In the beginning, D's symbol lookup mechanism was very simple and
> > straightforward: whenever an import statement is encountered,
> > symbols from an imported module are loaded and injected into the
> > symbol table at the current scope. This is straightforward to
> > implement (you literally translate "import xyz" as parsing xyz and
> > adding its public symbols to the current scope's symbol table).
> >
> > However, that led to counterintuitive behaviours like:
> >
> > void main() {
> > myFunc("abc");
> > }
> > void myFunc(string text) {
> > writeln(text); // prints "abc"
> > import std.conv;
> > writeln(text); // prints ""
> > }
[...]
> I would not like to be rude and reopen old wounds but this looks more
> a problem of `text` being either a variable or a function and as D
> allows function calls without params to me it looks like it has never
> been a problem of lookup. Now imagine std.conv.text is a global
> variable. That does not change anything. Order of declaration matters
> in the local scope.
It's not about `text` being a function called without parens; it's about
an imported module hijacking symbols in the local scope. The same
problem occurs in this situation:
```
// xyz.d
module xyz;
static immutable text = "haha you got hijacked";
// main.d
module main;
void main() {
myFunc("abc");
}
void myFunc(string text) {
writeln(text); // prints "abc"
import xyz; // N.B.: we never imported `text` explicitly
writeln(text); // prints "haha you got hijacked"
}
```
This is a problem because perhaps module xyz didn't declare `text` when
this code was written. Then later on, upstream rewrote the
implementation and added a declaration of `text`. Suddenly, unrelated
code in myFunc() has broken because its semantics silently changed from
under its carpet: the newly-added declaration of `text` in xyz has
hijacked the function parameter `text` in an unrelated module that just
happened to import it.
This is only one instance of the problem. Another instance concerns
*private* symbols in the imported module causing a conflict with a local
symbol in the importing module. (Remember, this is a logical consequence
of the simple and elegant concept that `import` simply injects symbols
into the local scope -- the injected symbols include private symbols.
Treating private symbols specially was one of the "inelegant" things
that complicated the implementation of imports, among other things.)
T
--
My stomach is flat. The L is just silent!
More information about the Digitalmars-d
mailing list