
btw, i always thought that it should be a way to overcome any export lists and go directly to module internals. limiting export is the way to protect programmer from errors, not security feature, and it should be left to programmer to decide when he don't need it. compilers should just be able to check whether some module/library imported abstractly or with internals too. this will render useless all those .Internals modules that now we need to add everywhere
You're not alone!-) This has been called "Open Implementation" (OI, a pre-cursor of aspect-oriented programming): http://www2.parc.com/csl/groups/sda/projects/oi/ They argue for an explicit auxiliary interface instead of full access to module internals. Since these same folks worked on meta-object protocols as well (at the meta-level, the boundaries can be bypassed entirely), that suggestion probably comes from experience. They do allow for the auxiliary interface to use meta-programming style features, though that depends on the language in question (in Haskell, type classes or type functions might be used instead, but rewrite rules and Template Haskell are also available). Open Implementation Design Guidelines http://www2.parc.com/csl/groups/sda/publications/papers/Kiczales-ICSE97/ is a short paper discussing a Set API/Open Implementation example.
I agree in principle, but GHC also uses that knowledge to optimize the code better - if a function is exported it has to produce the most polymorphic possible code for its type, if it isn't it can specialize better... that sort of thing.
That refers to optimization in the provider module. As the OI people argued, optimization in the client modules also needs to be taken into account. If the default one-size-fits-all-uses implementation behind the default API doesn't work well enough, there'll be a proliferation of library variants. If there is a way to fine-tune the implementation via an auxiliary API, much of that can be avoided. In other words, instead of half a dozen Maps and a dozen Array variants, there'd just be one of each, but with auxiliary interfaces that would allow client code to choose and tune the most suitable implementations behind the main interfaces. It isn't magic, though: if, say, even the auxiliary API doesn't allow you to say "thanks, but I know the length already", you're still stuck. But it does help to think about designing 2 APIs (the default functionality one and the auxiliary fine-tuning one) instead of offering only the choice of 1 API or full access to internals. Claus