DIP16: Transparently substitute module with package
Michel Fortin
michel.fortin at michelf.com
Thu Apr 5 16:32:15 PDT 2012
On 2012-04-05 21:43:24 +0000, Andrei Alexandrescu
<SeeWebsiteForEmail at erdani.org> 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
michel.fortin at michelf.com
http://michelf.com/
More information about the Digitalmars-d
mailing list