On 2012-04-04 14:08:34 +0000, "Steven Schveighoffer" <schvei...@yahoo.com> said:

On Mon, 02 Apr 2012 20:44:09 -0400, Michel Fortin <michel.for...@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.for...@michelf.com
http://michelf.com/

Reply via email to