
Wolfgang Jeltsch
The Yampa people and I (the Grapefruit maintainer) already agreed to introduce a top-level FRP namespace instead of putting FRP under Control or whatever.
The problem with a top-level namespace like FRP is that it is a cryptic acronym: it means nothing to a novice, and may be easily confused with other acronyms by an expert. I believe top-level names should _at_the_ _very_least_ be minimally descriptive of the category of things that live in it. So, I'd be fine with Control.Reactive.FRP, Control.Reactive.Yampa, etc, or even just Reactive.Yampa etc. I do understand that hierarchical classification is inherently problematic, and will never quite fit the ways we think of our modules. But the alternative being proposed here is neither more descriptive, nor more logical. In fact, it is an abandonment of description, in favour of arbitrary naming. A package called foo-1.0 containing a module hierarchy rooted at "Foo." tells me precisely nothing about its contents. It it were rooted at Military.Secret.Foo, at least I would have some clue about what it does, even if the category is inadequate or slightly misleading in certain circumstances. You may argue that only novices are disadvantaged by arbitrary names - once you learn the referent of the name, it is no longer confusing. However, I strongly believe that even experienced users are helped by the continuous re-inforcement of visual links between name and concept. After all, if you are collaboratively building a software artifact that depends on large numbers of library packages, it may not be so easy to keep your internal dictionary of the mapping between names and functionality up-to-date, and in sync with your colleagues. Being just a little bit more explicit in the hierarchy is a one-time cost at time of writing, that reaps perceptual benefits long into the future for yourself, and those maintainers who will follow you. Regards, Malcolm

On 17/06/2009 10:05, Malcolm Wallace wrote:
Wolfgang Jeltsch
wrote: The Yampa people and I (the Grapefruit maintainer) already agreed to introduce a top-level FRP namespace instead of putting FRP under Control or whatever.
The problem with a top-level namespace like FRP is that it is a cryptic acronym: it means nothing to a novice, and may be easily confused with other acronyms by an expert. I believe top-level names should _at_the_ _very_least_ be minimally descriptive of the category of things that live in it.
So, I'd be fine with Control.Reactive.FRP, Control.Reactive.Yampa, etc, or even just Reactive.Yampa etc.
I think this raises an interesting point. When we first started using hierarchical module names, we established a guiding principle: that the module name should reflect functionality first, so that the hierarchy can help you to find the functionality you're looking for. Including non-functionality-related information in module names should only be used to distinguish between multiple implementations of related functionality (e.g. Test.HUnit vs. Test.QuickCheck). That was before Hackage, which has largely taken over the role of helping users discover functionality. Obviously Hackage has a long way to go - it only has rudimentary categories right now, and in the past we've discussed having a more elaborate tagging scheme, but nevertheless Hackage seems like the right place to provide functionality-discovery. Before packages, there was a single module namespace shared by everyone. Now, for better or worse, there is a single package namespace shared by everyone, and the module namespace is essentially a free-for-all. Where does that leave module names? What are the advantages of having a rigidly-defined module hierarchy based on functionality classification? The only reasons I can think of are: * Choosing module names based on some generally agreed-upon guidelines makes it less likely that one package's module names will clash with another. * Packages that are conglomerations of different kinds of functionality (e.g. base) benefit from functionality-based module naming. * Source code doesn't refer to packages, it only refers to module names. So if you're trying to understand a piece of source code, it helps if the module names it imports are descriptive and unique. On the other hand, a module name tells you nothing of the provenance or the version of the module it refers to, so arguably source code without its dependencies is already less than useful. So why shouldn't OpenGL be naming its modules OpenGL.*, rather than Graphics.Rendering.OpenGL.*? Personally, I can't think of any sufficiently compelling reasons any more. Discuss! (replies set to libraries@haskell.org) Cheers, Simon

Simon Marlow wrote:
So why shouldn't OpenGL be naming its modules OpenGL.*, rather than Graphics.Rendering.OpenGL.*? Personally, I can't think of any sufficiently compelling reasons any more.
If everyone does that, it will flatten the Haddocks tree into one huge list. Some people told me they already use only textual search to navigate Haddocks, but I find the structure very helpful, including the higher-level names that hint at functionality. All of the other changes suggested in this thread would improve the usability of the Haddocks tree, provided that we standardize on them. But if everyone has their own idea about how to classify functionality, we're back to the same problem. Regards, Yitz

So why shouldn't OpenGL be naming its modules OpenGL.*, rather than Graphics.Rendering.OpenGL.*? Personally, I can't think of any sufficiently compelling reasons any more.
All of the other changes suggested in this thread would improve the usability of the Haddocks tree, provided that we standardize on them. But if everyone has their own idea about how to classify functionality, we're back to the same problem.
We have to remember that we live in a temporary situation. In the future, we are going to have many hackages, and every group of developers or companies or universities are going to have their own. We can't have a single rule for modules that extend beyond the most basic ones. It's good that everyone have their own idea on classification. That's how we can converge to good for all classification as time passes. What would be nice is to have the proper tools to easily reorganize that hierarchy as we wish. Today, we don't actually have module hierarchy, we just have '.' (dot) accepted in module names. It would be nice if we could say to our compiler that we wan't all modules under Control.FRP.Graphic.UI (and also in package X or Y) to be under MyBase, e.g., Control.FRP.Graphic.UI.Example would became MyBase.Example with no need for a import qualification. That would avoid clashes between diferent conflicting hierarchies. Best, Maurício

Am Donnerstag, 18. Juni 2009 18:20 schrieb Maurício:
It's good that everyone have their own idea on classification. That's how we can converge to good for all classification as time passes. What would be nice is to have the proper tools to easily reorganize that hierarchy as we wish.
Very good point! Best wishes, Wolfgang

Simon Marlow wrote:
Where does that leave module names? What are the advantages of having a rigidly-defined module hierarchy based on functionality classification? The only reasons I can think of are:
* Choosing module names based on some generally agreed-upon guidelines makes it less likely that one package's module names will clash with another.
+1.
* Packages that are conglomerations of different kinds of functionality (e.g. base) benefit from functionality-based module naming.
+1.
* Source code doesn't refer to packages, it only refers to module names. So if you're trying to understand a piece of source code, it helps if the module names it imports are descriptive and unique. On the other hand, a module name tells you nothing of the provenance or the version of the module it refers to, so arguably source code without its dependencies is already less than useful.
So why shouldn't OpenGL be naming its modules OpenGL.*, rather than Graphics.Rendering.OpenGL.*? Personally, I can't think of any sufficiently compelling reasons any more.
I think at this stage in the game, OpenGL.* is probably better. The way I see it there are two rather different kinds of modules (or module collections): * For module collections which have high utility across many different packages/programs (e.g. Data.Map, Control.Monad), having functionality-based names is helpful for solving name-clash and functionality-discovering/remembering issues. These modules are truly stand-alone "libraries" and are extremely composable (with other module collections) and extremely decomposable (from module collection into the constituent modules). * However, there are other collections of modules which are not "libraries" so much as "frameworks". While they're still (usually) composable, they're typically not decomposable. Often these are the results of taking an executable and shaving off some of the front-end details. Because of the non-decomposability, it makes sense to me to give each of these a top-level module name. Under the top-level they should be organized by functionality--- in the terms of the framework itself, not in the general terms shared by the "libraries". If many very-similar frameworks are anticipated (in particular, when more than one may be used in a single project), then it makes sense to collect them under a common top-level name. Test.* is a good example of this, though possibly the only one (or maybe Reactive.* as well). I'm not sure that I see rendering as a functionality that's sufficiently widely-used with many competing frameworks where more than one would reasonably used in a single project, in order to merit the Rendering.* prefix (but I don't play here, so I could be wrong). The Graphics.* prefix strikes me as too generic and unhelpful since it doesn't "mean" anything exactly: we could have an ASCII Art image renderer, should that be under Graphics.Rendering.* or Text.Rendering.*? -- Live well, ~wren

When we first started using hierarchical module names, we established a guiding principle: that the module name should reflect functionality first, so that the hierarchy can help you to find the functionality you're looking for.
I think the principle of describing functionality still holds good, and not merely for discovery. If everyone *really* called their modules by names like Arbitrary.Foo, Bar.Wibble, My.Utils, Other.Misc, etc, then having a hierarchy would indeed be totally useless. But in fact everyone does still attempt to give meaningful descriptive names to the leaf modules in the hierarchy, e.g. ...OpenGL.Shaders, ...OpenGL.Points, ...OpenGL.Framebuffer. If the leaf nodes continue to have descriptive names, then why not the roots?
What are the advantages of having a rigidly-defined module hierarchy based on functionality classification? The only reasons I can think of are:
And you proceed to list three very good reasons. Since the proposal to drop meaningful description from the hierarchy is a unforced change, perhaps someone would like to enumerate the disadvantages of the current scheme, and the advantages of the proposed change. So far, I have seen * The current names are long. (This is a physical disadvantage for the author who needs to exercise their fingers more, but is a cognitive advantage for the reader, who needs to think less.) * It is tricky to think of the right category. (I agree that "the" right category might not exist, but surely *some* relevant descriptive category is better than no category at all.)
So why shouldn't OpenGL be naming its modules OpenGL.*, rather than Graphics.Rendering.OpenGL.*? Personally, I can't think of any sufficiently compelling reasons any more.
The OpenGL example is quite a good one. People who know what the acronym means, understand at a glance that this hierarchy is about graphical rendering in 2D and 3D. Someone who does not know the meaning of the acronym will need to reach for Google. Because most of us programmers are very familiar with the name, we are blind to the potential for puzzlement to others. In this case, Google will help instantly because OpenGL is extremely widely used, and not just in Haskell. But there are many package names that are cryptic, far from unique, and Google is no help. If you don't believe me, here is a quick quiz. Guess at a glance what general category of functionality is provided by each of the following package names (taken from hackage). hgal hmm iff fec scc fst hybrid only lax tfp witness thrist vacuum mps alloy cap This is a quiz you can mark yourself. So how many did you get right (with the help of Google) *before* you looked at hackage? Now imagine that all packages provided this kind of naming scheme as the top-level roots of their contents. If you are an author of any of the above packages, please don't misunderstand me - I am not criticising the package-names at all. It is difficult to invent unique searchable identifiers that also immediately convey meaning. What I am saying is that, because of this difficulty, we need to see more than the mere package-name in source code that depends on it. Simple descriptive words in the hierarchy are just that - simple and descriptive. Regards, Malcolm
participants (6)
-
Malcolm Wallace
-
Maurício
-
Simon Marlow
-
Wolfgang Jeltsch
-
wren ng thornton
-
Yitzchak Gale