Hierarchical module namespace extension not sufficiently flexible

All, So here's the problem: we have a binding to a large foreign library (GTK) which we are trying to fit nicely into hierarchical module name space. It would live under Graphics.UI.Gtk Graphics.UI.Gtk.Button Graphics.UI.Gtk.Frame ... etc Now there are over 100 modules directly under Graphics.UI.Gtk and you don't want to have to import each one of them separately. Of course you will not use all of them in one module but you might reasonably use 20+ of them. So it'd be nice to be able to say:
import Graphics.UI.Gtk or import qualified Graphics.UI.Gtk as Gtk
But now we have a problem. These import directives import a flat namespace, or a flat namespace qualified by a single module alias (ie Gtk in the second example). But the Gtk modules are deliberatly designed to have hierarchical names. You cannot simply combine them all together into a flat namespace without falling back to the trick of prefixing each function name with the module name. So while we would like to be able for users to do this:
import Graphics.UI.Gtk
... Button.setLabel ...
They will instead have to say:
import Graphics.UI.Gtk
... buttonSetLabel ...
Which is one of the things that the hierarchical module namespace extension was trying to get rid of! All the other language bindings for Gtk (apart from C) use the former import and useage style. It doesn't make us look good! :-) So my question is: have I overlooked something or is this really not possible at the moment. And secondly, if it is currently not possible is there a 'nice' extension that would allow this sort of thing. (Where nice probably means Haskell98 compatible / 'doesn't' break existing programs) How about:
module Graphics.UI.Gtk (
module qualified Graphics.UI.Gtk.Button as Button ... ) where
import Graphics.UI.Gtk.Button
or equivalently(?):
module Graphics.UI.Gtk (
module qualified Button ... ) where
import Graphics.UI.Gtk.Button as Button
Duncan Ps there's a oddity I found where if you say:
module Foo ( module Bar )
import qualified Bar
then module Foo exports precisely nothing. But there's no error or warning.

So while we would like to be able for users to do this:
import Graphics.UI.Gtk
... Button.setLabel ...
I don't think you can do things like this with the current module system. One possible extension that might solve this problem is to allow partial qualified names, i.e. a qualified name only specifies enough of the _ending_ of the full qualified name to make it unambiguous. I think this is more or less compatable (of course it would invalidate some
Hello, Duncan Coutts wrote: ... programs but not a lot) as the current behavior is simply the special case where we specify the whole name. (Off the top of my head) I think this is quite easy to implement. For example in one of the Haskell front-ends we have here at OGI (Programatica), there is a "resolve" pass that replaces qualified names by the origianl names they refer to. During this pass we can detect ambiguous or undefined names. All one would have to do is modify the lookup function to check for suffixes rather then equality. I am not sure how other implementations work, but I'd imagine one would have to do something similar.
Ps there's a oddity I found where if you say:
module Foo ( module Bar )
import qualified Bar
then module Foo exports precisely nothing. But there's no error or warning.
This is the correct behaviour (at least according to the spec). The meaning of "module" exports is not as simple as one might expect. For details check out the report, for even more details you could take a look at "A Formal Specification of the Haskell 98 Module System". I agree that a warning in such situations may be nice. -iavor

Duncan Coutts wrote:
So while we would like to be able for users to do this:
import Graphics.UI.Gtk ... Button.setLabel ...
You are right, it is impossible to do this form of qualification,
either in Haskell'98 or in the hierarchical namespace extension.
The libraries list has discussed this issue before, in its earliest
days, but I think this is the first truly compelling example I have
seen where a further extension would be desirable.
"Iavor S. Diatchki"
One possible extension that might solve this problem is to allow partial qualified names, i.e. a qualified name only specifies enough of the _ending_ of the full qualified name to make it unambiguous.
Whilst this is an attractive suggestion (and a variant has been implemented in nhc98 since it first adopted hierarchical namespaces), it does not solve Duncan's problem. An abbreviated qualifier is still dependent on using the module name from the /import/ statement, and thus all imports must be named explicitly, if you want to qualify their contents. The desire is to use an abbreviation of the original /exporting/ module name, so that the exporting modules can be gathered together into a single container for import. Only one import statement is required, but it brings many qualifiers into scope. So it is beginning to look like the import/export mechanism needs to add another kind of entity to the set of namespaces it already handles (functions, classes, types, constructors, methods, fields, +qualifiers). On the plus side, this looks like a genuinely useful addition. On the minus side, import/export is already rather more complicated than it looks at first sight - do we want to add even more complexity? Regards, Malcolm

"Iavor S. Diatchki"
writes: One possible extension that might solve this problem is to allow partial qualified names, i.e. a qualified name only specifies enough of the _ending_ of the full qualified name to make it unambiguous.
Whilst this is an attractive suggestion (and a variant has been implemented in nhc98 since it first adopted hierarchical namespaces), it does not solve Duncan's problem. An abbreviated qualifier is still dependent on using the module name from the /import/ statement, and thus all imports must be named explicitly, if you want to qualify their contents.
The desire is to use an abbreviation of the original /exporting/ module name, so that the exporting modules can be gathered together into a single container for import. Only one import statement is required, but it brings many qualifiers into scope. ... This is a good point. When I was writing the above I was thinking that
Hello, perhaps we also add something like Java's .* imports, e.g: import UI.Gtk.* This is not very flexible as one has to import all modules. There is also the question of what exaclt it means, e.g. does it import all modules in the current directory, or also modules in sub-directories. Maybe that is not such a good idea... -Iavor

On Fri, 2004-12-17 at 14:26 +0000, Duncan Coutts wrote:
All,
So here's the problem: we have a binding to a large foreign library (GTK) which we are trying to fit nicely into hierarchical module name space. It would live under
Graphics.UI.Gtk Graphics.UI.Gtk.Button Graphics.UI.Gtk.Frame ... etc
Now there are over 100 modules directly under Graphics.UI.Gtk and you don't want to have to import each one of them separately. Of course you will not use all of them in one module but you might reasonably use 20+ of them.
So it'd be nice to be able to say:
[snip] Or as an alternative to exporting qualified names as I proposed before (ie Graphics.UI.Gtk exports the qualified name "Button.label") how about this: import qualified Graphics.UI.Gtk.* which just means import every module under Graphics.UI.Gtk qualified with it's module name so that then you could reference: Button.label A downside to such a scheme is that it might make it too easy to import internal modules or modules that are not supposed to be used together. I think on balance I prefer putting the power in the hands of the library author by letting modules export other modules' contents qualified with the module name module Graphics.UI.Gtk ( qualified module Graphics.UI.Gtk.Button as Button, ... Any other ideas of how to wrap large existing name spaces? The .Net and Java people would have the same problem: to use nice qualified names under the current module system, users would have to import 100's of modules. Duncan

On Sat, 05 Mar 2005 17:03:38 +0000, Duncan Coutts > module Graphics.UI.Gtk (
qualified module Graphics.UI.Gtk.Button as Button, ...
I like this idea a lot! It wouldn't break existing stuff (would it?), and it really seems like it should already be in there. I mean if you can import and export modules, it doesn't make sense that qualified imports are allowed but not qualified exports. This strategy also allows the library author some control over the library's structure. I might be missing something but this really does look "nice". /S -- Sebastian Sylvan +46(0)736-818655 UIN: 44640862

On Sat, 2005-03-05 at 22:15 +0100, Sebastian Sylvan wrote:
On Sat, 05 Mar 2005 17:03:38 +0000, Duncan Coutts > module Graphics.UI.Gtk (
qualified module Graphics.UI.Gtk.Button as Button, ...
I like this idea a lot!
Great. We "just" have to persuade other people around here of the same, in particular compiler implementors and the authors of the Hierarchical Modules Addenda.
It wouldn't break existing stuff (would it?), and it really seems like it should already be in there. I mean if you can import and export modules, it doesn't make sense that qualified imports are allowed but not qualified exports.
I think the reason it was not added before is down to the fact that modules don't really export other modules. They just export other modules contents. (Also it was a deliberately conservative extension.) Exporting qualified names doesn't really change that, we're just exporting the contents of a module but with qualified names.
This strategy also allows the library author some control over the library's structure. I might be missing something but this really does look "nice".
You mean it would allow a 'virtual' structure to be exported that does not match the actual internal structure of the library? I suppose that's true. I think this is probably a bonus (so long as library authors use it sensibly). For example in Gtk2Hs, in actual fact we do not have Graphics.UI.Gtk.AboutDialog we have Graphics.UI.Gtk.Windows.AboutDialog That is we have an additional "category" layer. Otherwise we would have all 130 modules directly in the Graphics/UI/Gtk/ directory which we would find much harder to manage. So it would be nice to keep this structure but to export a 'virtual' module structure that does not mention the category. ie: module Graphics.UI.Gtk ( qualified module Graphics.UI.Gtk.Windows.AboutDialog as AboutDialog ... ) where import Graphics.UI.Gtk.Windows.AboutDialog ... Duncan

Hello,
On Sun, 06 Mar 2005 12:21:01 +0000, Duncan Coutts
On Sat, 2005-03-05 at 22:15 +0100, Sebastian Sylvan wrote:
On Sat, 05 Mar 2005 17:03:38 +0000, Duncan Coutts > module Graphics.UI.Gtk (
qualified module Graphics.UI.Gtk.Button as Button, ...
I like this idea a lot!
Great. We "just" have to persuade other people around here of the same, in particular compiler implementors and the authors of the Hierarchical Modules Addenda.
It wouldn't break existing stuff (would it?), and it really seems like it should already be in there. I mean if you can import and export modules, it doesn't make sense that qualified imports are allowed but not qualified exports.
I think the reason it was not added before is down to the fact that modules don't really export other modules. They just export other modules contents. (Also it was a deliberately conservative extension.)
Exporting qualified names doesn't really change that, we're just exporting the contents of a module but with qualified names.
This seems like quite a significant change from the way the module system works at the moment (not that this is a bad thing). Currently a module can only export "entities", i.e. the things that names refer to. It is completely up to the importing module to decide what names to introduce for the imported entities. With this suggestion a module would have to export not only entities but also hints instructing the importing module how to name things. It looks like this could work without too much difficulty. Presumably the qualified names introduced by the importing moudle should be computed by joining the "as" clause of the import with the hint that came along with the entity (if any). We probably don't want to have multiple hints, so that each entity can have at most one hint associated with it. -Iavor

Duncan Coutts
On Sat, 2005-03-05 at 22:15 +0100, Sebastian Sylvan wrote:
On Sat, 05 Mar 2005 17:03:38 +0000, Duncan Coutts > module Graphics.UI.Gtk (
qualified module Graphics.UI.Gtk.Button as Button, ...
I like this idea a lot!
Great. We "just" have to persuade other people around here of the same, in particular compiler implementors and the authors of the Hierarchical Modules Addenda.
Well, as an author of the Hierarchical Modules addendum, and as a compiler maintainer, I am already reasonably convinced of the utility of this suggestion. It does significantly alter the semantics of import/export, in a way that the original Hierarchical Modules addendum does not, but as Iavor pointed out, this is not necessarily a bad thing. What we now need is a precise definition. After that, contributions of code to implement it would also be welcome. :-) Regards, Malcolm
participants (6)
-
Duncan Coutts
-
Duncan Coutts
-
Iavor Diatchki
-
Iavor S. Diatchki
-
Malcolm Wallace
-
Sebastian Sylvan