On 12/07/2010 12:43, John Meacham wrote:
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.
Right. I like the idea of packages being able to declare re-exported
modules, indeed I considered doing this in GHC (when we needed base3)
but decided not to mainly because we would still need PackageImports,
and once you have PackageImports you can implement re-exports using
that, albeit with more boilerplate. The advantage of direct re-exports,
as you say, is that it avoids a conflict when the module is imported.
However, since some of the modules would conflict anyway, there didn't
seem to be much advantage in avoiding the conflict in some cases but not
others.
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.
Isn't that what PackageImports lets you do?
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.
No, there's no problem with mixing packages in that way.
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).
And hopefully things will improve over time, as fewer packages will need
to depend on base. We could also start pulling out APIs that are
currently in base into separate packages, without actually pulling out
the code - e.g. concurrency, and that would be a good way to migrate
people away from depending on base, but without breaking everything.
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
Interesting. This is quite a different set of decisions to the way GHC
does things, so I look forward to comparing some benchmarks. My
intuition is that if allocation is anything more complicated than "reg
+= size; if (reg > lim) { ... }" then you have a lot of work to do to
make up for the overhead, but let's see!
Cheers,
Simon
_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe