DIP16: Transparently substitute module with package
Michel Fortin
michel.fortin at michelf.com
Wed Apr 4 09:33:26 PDT 2012
On 2012-04-04 14:08:34 +0000, "Steven Schveighoffer"
<schveiguy at yahoo.com> said:
> On Mon, 02 Apr 2012 20:44:09 -0400, Michel Fortin
> <michel.fortin at michelf.com> wrote:
>
>> Whereas if the fully-qualified name of a module becomes ambiguous
>> because of a symbol in another module, there is no way to disambiguate.
>> All you can do is avoid importing the two conflicting modules
>> together, just like when you encounter two headers trying to define
>> the same symbol in C/C++.
>
> How does this happen? The FQN cannot be ambiguous.
Sure it can if I follow DIP16, because module names can become ambiguous.
Let's try this with an example. First, let's define a pretty standard module:
std/algorithm/sort.d:
module std.algorithm.sort;
void sort(T)(T[] array);
Here the fully-qualified name of the sort function is
.std.algorithm.sort.sort. But according to DIP16's lookup rules, the
sort function is also available (if not ambiguous) at:
std.sort
std.algorithm.sort
Question 1: since there is already a module at .std.algorithm.sort,
doesn't the module name become ambiguous with the sort function it
itself contains?
Let's assume the module's name take priority and does not conflict so
we can continue. Now we create the package.d file:
std/algorithm/package.d:
import std.algorithm.sort;
And now I write this somewhere in my code:
std.algorithm.sort
Question 2: does std.algorithm.sort refer to the std.algorithm.sort
*module* or to std.algorithm.package.sort *function* publicly imported
from the std.algorithm.sort module?
Again, we could decide that the module takes priority. But having
symbols take priority over one another is not how D has resolved
ambiguities up to now; what D does usually is make it a hard error. If
we make it an error the fully-qualified name of anything in the
std.algorithm.sort module becomes inaccessible. If we do not make it an
error, the module name shadows the function imported in the package.
And the problem with shadowing is that it can silently change what code
you're calling depending on what you've imported (if you need an
example, just ask).
You might think I'm trying to split hair in four to find flaws, that no
one is going to do things that dumb, but I unfortunately think the
problematic pattern is already quite common. How many times have we
seen modules containing a class, variable, or function having the same
name as the module's name? What should happen when you publicly import
those modules in the package.d file?
The practice might not be too prevalent in Phobos because modules tend
to do a lot of things and are therefore named more generically, but it
still happens. For instance:
std.array.array
std.getopt.getopt
std.regex.regex
Say you wanted to create a package.d file directly for the whole
package std, what should be done for those?
--
Michel Fortin
michel.fortin at michelf.com
http://michelf.com/
More information about the Digitalmars-d
mailing list