[Haskell-cafe] Re: [Haskell] ANNOUNCE: Haskell 2010 Report (final)

John Meacham john at repetae.net
Mon Jul 12 07:43:48 EDT 2010


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/


More information about the Haskell-Cafe mailing list