Hacker News new | past | comments | ask | show | jobs | submit login

> There is this stream computation library

Sometimes Haskell allows you to easily implement algorithms that would be, comparatively, much more painful to write in c++. There are stream fusion libraries, and it's important to know them. You can do a lot with plain Haskell before you need to start worrying about CPU instructions. Things like linear algebra, matrix multiplication kernels are exceptions.

> Haskell FFI is painful to work

That link is three years old, and I think I disagree with some of things he says. I agree that haskell ffi is poorly documented. But he also says it is "deeply strange". Without using any extra tools, I would say it is a little laborious, but conceptually very simple. He also says he couldn't figure out how to return anything other than integers.

Think about it this way. Haskell makes no mention of how its objects are laid out in memory. If you pass a native Haskell object (a boxed int, or a struct) to C, C code will not ever be able to unwrap it without making guesses about memory layout. What Haskell expects you to do is to do this yourself: if a structure consists of an integer and a double, you define (yourself) a function that takes a pointer, and lays out the integer and the double in the memory as your C code would expect to find them there.

Then every FFI call takes the form

1. Allocate a chunk of memory.

2. Store your Haskell object into that memory, using your layout. This is what the `poke` function does.

3. Pass the pointer to a C function.

4. C function reads and writes to that chunk of memory.

5. When C function returns, read from the memory and pack the results into a Haskell object. This is the `peek` function.

5a. Quite often a C function would return a success code anyway, and the actual return value will be written to a pointer passed to the C function. This is really common.

6. Deallocate the chunk of memory.

6a. Notice that no assumptions were made about internal object layout, except that you have to know what layout the corresponding C structure is expected to have.

This might also be the reason why it's unintuitive how to return complicated objects from C. The complicated objects need to be explicitly unpacked and stored into a Haskell object. There are tools that automate this process, but the tool-less FFI is straightforward once you figure it out.

Here is the layout GHC actually uses: https://ghc.haskell.org/trac/ghc/wiki/Commentary/Rts/Storage...

This is maybe a bit unintuitive, but it makes sense to me.




Thanks for your overview. I had not done yet a deep analysis of the FFI myself, your summary clarified things.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: