On 2012-04-05 21:43:24 +0000, Andrei Alexandrescu <[email protected]> said:

I think we should be looking for a solution that not only allows replacing module -> package transparently, but also allows people to import the newly introduced fine-grained modules.

I think it'd be valuable too. But how do you do that without creating ambiguous fully qualified names?

One way would be that by importing a module inside a package, the compiler would check first that the package file contains no symbol with that module name. In other words, if you import std.algorithm.sorting, it'd check that "algorithm" is not a symbol defined in the "std" package file (if it exists for std) and that no "sorting" symbol exists in the "std.algorithm" package file. That would work. But the problem is that if the package file publicly imports all of its submodules, then you'll need to parse all the imported files to determine if the module you're trying to import conflicts with a package-level symbol.

A more practical option would be limit the package files to only two things:

1. a list of modules to import when you import the package (importing the package would be akin importing all modules in this list)

2. a list of symbols aliased in the package's namespace (aliased symbols can be accessed using the package name as a prefix and through selective imports)

Since the list of aliases is stored directly in the package file, reading the package file to get the names of each alias is enough to tell there is no conflict with the module name when you're trying to import it. No need to open the other modules the package refers to, or to resolve the symbols the aliases refer to: you only need the name of each alias to verify there is no conflict.

For instance, a package file could look like this:

        package std.algorithm;

        // modules to import when a file is importing the package
        // (those are not imported inside this package's namespace)
        module std.algorithm.sorting;
        module std.algorithm.mapping;
        ...

        // symbols to alias to this package namespace
        // (importing a module with one of these names is an error)
        alias std.algorithm.sorting.completeSort  completeSort;
        alias std.algorithm.sorting.isSorted      isSorted;
        alias std.algorithm.sorting.partialSort   partialSort;
        alias std.algorithm.sorting.schwartzSort  schwartzSort;
        alias std.algorithm.sorting.sort          sort;
        ...

The drawback is that it's hard to maintain the list of fully-qualified names up to date if you change it in the various modules. But if the goal is only to preserve backward compatibility, creating that list of aliases could be a one-time thing. New symbols would continue to be imported when you import std.algorithm, but they'd not be available directly under std.algorithm: you'd need to use std.algorithm.sorting.newSort if you find yourself in a situation that requires a fully-qualified name.


--
Michel Fortin
[email protected]
http://michelf.com/

Reply via email to