Since both ruby and Haskell supports FFI,
- Is it possible to call Haskell code from ruby, may be through FFI ?
- Is there any Haskell binding in Ruby ?
Since both ruby and Haskell supports FFI,
I haven't seen it done before, but it's possible.
libruby
. Your main executable will be written in Haskell, which will call ruby_init()
and related functions, in order to run the Ruby interpreter in-process. This does allow you to run arbitrary Ruby code, though.hs_init()
, and can only access foreign export
ed functions.You'll need to write glue code, some in C, to get either of those two options working.
I don't know what your requirements are, but this is what I'd go for -- it's a lot easier.
@ephemient, I am actually looking for someways to use Ruby (high level + dynamic) to be the main controller logic and invoking haskell for large amount of data crunching (functional + speed)
I think native binding is close to non-existence, apart from this tweet http://twitter.com/BlurredWeasel/status/1321484127
Using JSON RPC will be probably the easiest way to implement where there is a thin wrapper in ruby to (method_missing) to invoke haskell over JSON/Socket.
JSON has the advantage of being able to easily map primitives to native types between various languages..
class SciHs
def method_missing(method, *args)
// json encode
// request Haskell over tcp socket or unix pipes
// json decode
end
end
Other alternative for fast number crunching in ruby (+ functional style)
Thoughts anyone?
I am not sure about the Haskell side, but here is a cool video from Mountain West Ruby Conf 09 about working with FFI from Ruby. It looks like a pretty nice interface.
http://mwrc2009.confreaks.com/13-mar-2009-16-10-ffi-jeremy-hinegardner.html
I tried exactly this (I'm the one from the mentioned tweet).
I didn't think of the libruby approach, but I spent a fair amount trying to use ruby's FFI to wrap an exported function from haskell, and could never quite get it to all link and run.
If you look at haskell's FFI examples, you'll see that they all include a C main() function. Since ruby's FFI doesn't have (and can't have) a main(), that won't work. If you try without that, you end up with weird link errors.
I can share what I have with you, ping me on freenode (cschneid), or on twitter (BlurredWeasel).
I'm a bit late to this discussion, but I'm currently writing a bridge between Ruby and Haskell. It's at http://github.com/mwotton/Hubris - it's a binding that works at the C level. Still at a very early stage of development, though.
GHC 6.12.1 supports building dynamic libraries on Linux. Try something like:
{-# LANGUAGE ForeignFunctionInterface #-}
module Example where
import Foreign.C.Types
fibonacci :: Int -> Int
fibonacci n = fibs !! n
where fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
fibonacci_hs :: CInt -> CInt
fibonacci_hs = fromIntegral . fibonacci . fromIntegral
foreign export ccall fibonacci_hs :: CInt -> CInt
#include <stdlib.h>
#include "HsFFI.h"
void
example_init (void)
{
hs_init (NULL, NULL);
}
void
example_exit (void)
{
hs_exit ();
}
require 'dl'
require 'dl/import'
module Example
extend DL::Importable
dlload "./libffi-example.so"
extern "void example_init()"
extern "void example_exit()"
extern "int fibonacci_hs(int)"
end
Example.example_init
1.upto( 40 ) do | x |
puts "#{ x } -> #{ Example.fibonacci_hs x }\n"
end
Example.example_exit
GHC=ghc-6.12.1
libffi-example.so: Example.o wrapper.o Example_stub.o
$(GHC) -o $@ -shared -dynamic -fPIC $^ -lHSrts-ghc6.12.1
Example_stub.c Example_stub.h Example.o: Example.hs
$(GHC) -c -dynamic -fPIC Example.hs
Example_stub.o: Example_stub.c
$(GHC) -c -dynamic -fPIC Example_stub.c
wrapper.o: wrapper.c Example_stub.h
$(GHC) -c -dynamic -fPIC wrapper.c
clean:
rm -f *.hi *.o *_stub.[ch] *.so
make
ruby script.rb