
On Thu, Jan 5, 2012 at 5:44 PM, Joachim Breitner
Anyways, I’m just brainstorming a bit, although it seems I’m only turning up ideas that have been dismissed already...
It is good to hash through these things. =) On a related note, which doesn't solve the general problem, I have been working with Dan Peebles on a nice set of MPFR bindings for my own purposes using custom foreign prims. I unpacked the main MPFR structures and let the ghc garbage collector move everything around, like it does with GMP itself. We've been able to get a version that ALMOST works as expected. That is to say it works perfectly unless you need to access a function that pulls from its built-in constant cache. (MPFR internally caches the result of computing the first n digits of pi or log of 2, etc. growing the cache as you demand longer numbers.) Dan was able to swap out the ghc gmp allocation hook for a slightly slower one that checks to see if it is being called from the MPFR cache management function, and diverting the allocation back to malloc. Ideally we would swap the handler in an initializer when the library loads, and this works perfectly in ghc, but not ghci -- which apparently links in libraries in a way where c++ style initializers don't get invoked? A 'replaceAllocator' IO action that swaps the gmp allocation hook isn't a very Haskelly solution either, because I'd prefer to just have it look like another numeric type. Dan is currently investigating including a patched copy of MPFR in the haskell package, which doesn't try to use the built-in allocator for the constant cache. This is where it becomes relevant to the discussion at hand, because it would effectively involve linking in our own copy of MPFR, making distributions unhappy. But another option would be to unsafePerformIO that initializer, which would add a bit of overhead, going through an indirection to make sure that replaceAllocator had been forced, perhaps it wouldn't be too bad: Something like: replaceAllocator :: () replaceAllocator = unsafePerformIO replaceAllocatorIO {-# NOINLINE replaceAllocator #-} instance (Rounding r, Precision p) => Floating (Fixed r p) where pi = replaceAllocator `pseq` mpfr_pi ... This doesn't address general purpose use of third party libraries that happen to internally rely upon GMP, however. Or rather, if it does, the methodology it would lead to would be one of bringing over all of their internals into Haskell. ;) -Edward Kmett