19312, "mppf", "should it be possible to define a module that shadows an automatically included symbol?", "2022-02-25T15:19:01Z"
This is a spin-off from definition of shadowing is inconsistent between variables and functions · Issue #19167 · chapel-lang/chapel · GitHub
The automatic modules are implicitly use
d at the start of each module. Should it be possible to create a module that shadows something from these automatic modules?
Here is an example (Note that today, Math is an automatic module and defines param e
):
module ReplaceE { param e = 10; }
module Program {
// use AutomaticModules / use Math; is effectively here but implicit
use ReplaceE;
e; // should this refer to ReplaceE.e or be ambiguous?
}
I think that the main argument that I know of in favor of allowing shadowing here is that we would like to be able to add automatically-included functions and variables without breaking programs.
Here is a story about how that could come up. Suppose we have this:
module AutomaticModules { }
module DefinesFoo { var foo = 10; }
module Program {
// use AutomaticModules; is effectively here but implicit
use DefinesFoo;
foo; // OK, refers to DefinesFoo.foo
}
Now suppose that in StandardLibrary
, we add a const foo
:
module AutomaticModules { var foo = 20; }
module DefinesFoo { var foo = 10; }
module Program {
// use AutomaticModules; is effectively here but implicit
use DefinesFoo;
foo; // Is this now an ambiguity?
}
Do we want the above program to continue to compile? I would suppose so - because I'd think that adding a top-level variable to the automatic modules should be a non-breaking change.
I think another viewpoint on this issue is - suppose everybody were using import
, what would happen? It would get the user's foo
and not give an ambiguity error. Here is an example:
module AutomaticModules { ... }
module DefinesFoo { var foo = 10; }
module Program {
import AutomaticModules;
import DefinesFoo.foo;
foo; // always refers to DefinesFoo.foo even if AutomaticModules adds a foo
}
So, if we arrange for foo
to always refer to DefinesFoo.foo
even in the use
statement case above, we are making the situation more consistent with what we would regard as the good behavior from import
.
I think the main alternative to this strategy is to avoid adding symbols to the set of automatically-included symbols and to consider it a breaking change when we do.