Problem with hierarchical libraries in Hugs compared to ghc/nhc98
When trying to make our Haskell tracer Hat work with Hugs (November 2002) I noticed that * Hugs' implementation of hierarchical libraries differs from those of ghc and nhc98, and * Hugs' implementation choice makes it more restrictive than ghc/nhc98 A simple example: There is module B in file B.hs There is module Test.B in file Test/B.hs There is module Test.A in file Test/A.hs Module Test.A contains "import B". When compiling module Test.A both nhc98 and ghc imports module B from file B.hs. In contrast, Hugs imports module Test.B from file Test/B.hs and then stops with an error, because the module name is wrong. The simple reason why Hugs behaves so is that when searching a module it *always* searches the current directory (* where the import was demanded *) first. Only afterwards the paths set with the -P option are searched. I know that we generally try to avoid specifying filename and directory issues. However, this is not really a filename issue, but a problem of relative and absolute module names (wrt possibly several hierarchies). An "import B" in module Test.A could mean either module B or module Test.B. I suggest that the absolute module name takes precedence, because otherwise there is no way to import module B from module Test.A, whereas you can always import module Test.B from module Test.A by saying "import Test.B". I admit that this has the slight disadvantage that moving a set of modules into the hierarchical library will require not only changing all module names at the top but also in every import declaration, to not inadvertedly import the wrong module. So in the end this suggests that we should not allow relative module names at all. Note that this proposal still allows the current directory (of Hugs or in which the compiler was started) to be the root of the hierarchy that is searched first. In fact, this is probably the desirable default behaviour. Currently the hierarchical library proposal http://www.haskell.org/~simonmar/libraries/libraries.html does not say much about the semantics of the hierarchical module names. It really should. I'd very much like to hear other people's opinion on this (especially the Hugs maintainers'). The current behaviour of Hugs makes it impossible for Hat to work with Hugs. Hat creates a shadow hierarchy of transformed libraries: the transformed variant of Prelude is Hat.Prelude, the transformed variant of Control.Arrow is Hat.Control.Arrow etc. Nearly all of the transformed modules import both Prelude and Hat.Prelude ... Olaf -- OLAF CHITIL, Dept. of Computer Science, The University of York, York YO10 5DD, UK. URL: http://www.cs.york.ac.uk/~olaf/ Tel: +44 1904 434756; Fax: +44 1904 432767
On Fri, Mar 07, 2003 at 02:35:47PM +0000, Olaf Chitil wrote:
When trying to make our Haskell tracer Hat work with Hugs (November 2002) I noticed that
* Hugs' implementation of hierarchical libraries differs from those of ghc and nhc98, and * Hugs' implementation choice makes it more restrictive than ghc/nhc98
A simple example: There is module B in file B.hs There is module Test.B in file Test/B.hs There is module Test.A in file Test/A.hs Module Test.A contains "import B".
When compiling module Test.A both nhc98 and ghc imports module B from file B.hs. In contrast, Hugs imports module Test.B from file Test/B.hs and then stops with an error, because the module name is wrong.
The simple reason why Hugs behaves so is that when searching a module it *always* searches the current directory (* where the import was demanded *) first. Only afterwards the paths set with the -P option are searched.
[noble attempt at rationalizing Hugs's behaviour omitted]
This is a clear flaw in Hugs (long known, but hard to fix). A workaround is to add the -X option to stop it adding the extra directory.
Ross Paterson wrote:
On Fri, Mar 07, 2003 at 02:35:47PM +0000, Olaf Chitil wrote:
The simple reason why Hugs behaves so is that when searching a module it *always* searches the current directory (* where the import was demanded *) first. Only afterwards the paths set with the -P option are searched.
This is a clear flaw in Hugs (long known, but hard to fix). A workaround is to add the -X option to stop it adding the extra directory.
Thank you very much for pointing me to the -X option which I had not noticed before. Why is it hard to fix if -X actually exists? Why not have -X as default? Is the current default behaviour good for anything? I still suggest putting some semantical description into the hierarchical libraries extension document, so that people like me do not jump to wrong conclusions because of the similarity with directory structures. Olaf -- OLAF CHITIL, Dept. of Computer Science, The University of York, York YO10 5DD, UK. URL: http://www.cs.york.ac.uk/~olaf/ Tel: +44 1904 434756; Fax: +44 1904 432767
hello, Olaf Chitil wrote:
...
I know that we generally try to avoid specifying filename and directory issues. However, this is not really a filename issue, but a problem of relative and absolute module names (wrt possibly several hierarchies). An "import B" in module Test.A could mean either module B or module Test.B. I suggest that the absolute module name takes precedence, because otherwise there is no way to import module B from module Test.A, whereas you can always import module Test.B from module Test.A by saying "import Test.B".
why not fix the design to take this into account? one can have two ways to refer to modules - relative and absolute (just like in the file system, which years of experience show works pretty well). import .Test.A -- refers to an absolute path -- (relative to a user specified root) -- i.e. $HS_PATH/Test/A.hs import Test.A -- is a path relative to the location of -- the current module, i.e. -- [location of module]/Test/A.hs in fact it seems that a nice way to implement separate compilation in a concrete implementation could be to have 2 top level paths: $HS_LIBS $HS_PROJ the implementation should look for absoulte files relative to both of those, but it would expect that if something is found in the $HS_LIBS path it will be already compiled and not look for source code. just an idea. i also have another question about the hirarchical modules design -- why does one have to duplicate the path to a particular file inside the file itself? i.e. what is the point of the module name within the file? it seems that all haskell implementations assume that the module name and file name are the same (and this seems perfectly reasonable), and with the hirarchical name space this is even more the case. and for example C programers never specify the name of the current file within the file. why do we want to do it? just wondering iavor -- ================================================== | Iavor S. Diatchki, Ph.D. student | | Department of Computer Science and Engineering | | School of OGI at OHSU | | http://www.cse.ogi.edu/~diatchki | ==================================================
I know that we generally try to avoid specifying filename and directory issues. However, this is not really a filename issue, but a problem of relative and absolute module names (wrt possibly several hierarchies). An "import B" in module Test.A could mean either module B or module Test.B. I suggest that the absolute module name takes precedence, because otherwise there is no way to import module B from module Test.A, whereas you can always import module Test.B from module Test.A by saying "import Test.B".
why not fix the design to take this into account? one can have two ways to refer to modules - relative and absolute (just like in the file system, which years of experience show works pretty well).
import .Test.A -- refers to an absolute path -- (relative to a user specified root) -- i.e. $HS_PATH/Test/A.hs import Test.A -- is a path relative to the location of -- the current module, i.e. -- [location of module]/Test/A.hs
An interesting idea, but I have two comments on it. First, I think using a . at the beginning of the module name is not visual enough to be easily seen. Something as important as which module to pick should have something that stands out as absolute or relative. Second, I would prefer it select relative offset modules before checking for absolute modules. I would imagine that the designer of a module would want associated modules inserted more often than those with the same name but not associated with the current module. (Actually, the second comment is not on your post, but on the post you commented on).
i also have another question about the hirarchical modules design -- why does one have to duplicate the path to a particular file inside the file itself? i.e. what is the point of the module name within the file? it seems that all haskell implementations assume that the module name and file name are the same (and this seems perfectly reasonable), and with the hirarchical name space this is even more the case. and for example C programers never specify the name of the current file within the file. why do we want to do it?
Often, in C++ and Java, one has many modules in a file, but only one that is meant to be visible to the outside world. Other modules might be name _ext_X or _private_X or something along those lines. By requiring a module name, you allow the primary module to start anywhere in the file as well as other modules to be defined in the file. Furthermore, you allow files that don't contain modules, something very important for quick prototyping. Thanks! Tanton
participants (4)
-
Iavor S. Diatchki -
Olaf Chitil -
Ross Paterson -
Tanton Gibbs