Hubris and GHC 6.12: an experiment in dynamic linking 3
So, Hubris has got to be a bit more of a serious tool since the last time I posted about it. In preparation for a talk at RORO Sydney, I've been hacking madly, and now have full support for all of the basic types but hashes and works with GHC HEAD (JHC crashes for arrays at the moment, as I'm monstrously abusing unsafePerformIO).
To steal from one of my RSpec tests, it can be used from Ruby like this:
it "returns a haskell list as an array" do
t=Target.new
t.inline("elts (T_FIXNUM i) = T_ARRAY $ map T_FIXNUM $ take i [1..]
elts _ = T_NIL" )
t.elts(5).should eql([1,2,3,4,5])
t.elts("A Banana").should eql(nil)
end
The interface could be cleaned up a bit: currently, everything has to be marshalled into a Ruby value(whether that's an array, hash or primitive type.) It'd be nice not to have to use the T_FIXNUM wrapper to indicate the type of the Haskell function - using ghc-src-exts, I could discover the type of the underlying function and wrap it automatically. Next release, perhaps. Anyway, this all only works on Linux for the moment, as GHC's support for dynamic libraries on Mac has bitrotted a bit. While Duncan Coutt's got the Linux side running sweetly, Daniel Peebles is currently having a look at the dynlib support on Mac, and I'm going to try to help out in whatever limited way I can - with any luck it'll all be ready for 6.12, which is coming out Real Soon Now and is full of tasty treats like ThreadScope.
Under the hood, it's actually pretty simple. Once you have dynamic library support, it's reasonably easy to take a chunk of Haskell, collect the top-level identifiers, wrap them for access from C-land, and compile a library. Likewise, accessing dynamic libraries from Ruby is very old news indeed. There's a lot of plumbing involved, working out exactly what flags various tools need to build the libraries correctly, but you never see that it in operation: it's software that just disappears into the background.
Anyway, check it out, see what you think. Collaborators are always welcome, and there's still a heap of things to do.

This is very cool. I am BlurredWeasel on twitter, and was looking at doing Haskell interop earlier this year, but at that time, GHC was being a bastard, and LHC was still too immature.
What kind of speed are you getting with all the marshalling and unmarshalling that appears to be going on?
Very very cool. Thanks for all the work on this. I’m looking at mixing up a Ramaze Web front-end to Haskell innards.
And what’s with the weasels? :) (Hey Chris!)
@chris: yeah, I started on JHC. It’s still not quite production-ready, but it made an excellent scaffold - it compiles to straight C with no dependencies. No benchmarks yet, for the stuff I want to use it for, there’s not a huge amount of data to shuffle around. I’m still undecided on the best way to handle the marshalling: it’s a real trade-off between speed and convenience. Currently convenience is winning.
@James: Hey, good to see you (and thanks for the patches). Hope it’s useful to you.