
On Mon, Jul 12, 2010 at 10:07:28AM +0100, Simon Marlow wrote:
The story we tentatively plan to provide in GHC 6.14.1 is a haskell2010 package that provides exactly the API specified by the report (by definition, since the source was used to generate the report :-). The modules of haskell2010 overlap with base, so it will be impossible to depend on both haskell2010 and base, without using non-portable extensions like PackageImports.
The way Jhc handles module overlap with packages is that it allows re-exporting modules from different libraries transparently, and reports conflicts lazily, as with normal haskell identifiers. For example, the 'haskell98' package might have a field 'Reexport-Modules:' with an entry 'Compat.Haskell98.Prelude as Prelude', meaning that if you pass -phaskell98 on the command line, you get a 'Prelude' that is transparently remapped to 'Compat.Haskell98.Prelude' under the scenes. This means that you can happily have both -phaskell98 and -phaskell2010 and get access to all of both their modules because they have identical 'Prelude' modules so will both re-export the same underlying module (implemented in some common base package) and there will be no conflict reported. Just like it is okay if you import the same haskell function from two different modules as long as they refer to the same original function. Things are trickier if they do both -phaskell2010 and -pghc-base-3 since they conflict on some module names, there is nothing wrong with linking against both of them, but if you do an 'import Data.List' then a conflict will be reported as that particular module is different between the two. But if you only use the 'Prelude' or other modules that coincide, there will be no trouble. I think the ability for a package to define an 'interface' built up from other re-exported modules will be very useful going forward, I am not sure how hard something like that would be to implement in ghc, but it may be worth it in the future.
I hadn't realised before, but this situation is better for portability, because it discourages people from using base package modules in pure Haskell 2010 code. The downside is exactly the reverse: if you wanted to use modules from base, then you don't get to use the pure Haskell 2010 modules too (although the base versions are virtually identical at the moment).
I would worry that it would discourage people from using 'haskell2010' at all to some degree. Are there issues in ghc with one library being built on haskell2010 and another being built on base and a third wanting to use both of them? If not, then I don't think it will be too bad. The situation will be no worse than it is now, as it is, pretty much every library out there depends on 'base' making it theoretically incompatible with jhc. (in practice, most things compile just fine if I simply ignore the overly pedantic cabal dependencies and just add the obvious dependencies based on imports, aka, the franchise heuristic).
jhc 0.7.4 which supports garbage collection and a speedier runtime and better support for external build systems will be out soon. My goal is one more point release before 0.8.0 which will have full haskell 2010 and 98 support.
I haven't looked at the new jhc yet, but I have a question about the GC support: is it conservative or accurate? If accurate, how are you finding the pointers - a shadow stack?
In the past I just had the boehm GC and the cross your fingers and hope static analysis can catch everything options. But as of 0.7.4 I have a real gc that I hope to make the new default in the next major release. (enabled with -fjgc on the command line) It is an accurate GC that is implemented in portable C. I am using something based on the paper 'Accurate garbage collection in an Uncooperative Environment'[1] though the technique was independently discovered. I always pass the GC parameter as the first argument to functions, which is mapped to the same register, so I effectively have a dedicated register without having to resort to a dedicated declared register in gcc. Plus I can omit the parameter in leaf functions that don't allocate and free up the register for normal use. I compile with -mregparm=2 on i386 so the first two arguments to a function get mapped to registers. I found that an independent shadow stack actually is faster than using the linked version described in the paper, (though, still passing around a pointer to the top of the stack as described), my theory being that taking the address of a stack allocated object will inhibit certain gcc optimizations. The underlying allocator is based on Bonwick's slab allocator[2] which works quite well for a haskell runtime, I have a slab for each type, so a slab of 'cons' cells, a slab of size 3 tuples, and so forth. [1] http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.19.5570 [2] http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.143.4374 John -- John Meacham - ⑆repetae.net⑆john⑈ - http://notanumber.net/