Ccall vs. capi: discouraged?

I’m currently wrapping a C(++) API onto Haskell and stumbled upon this Haskell-Wiki page stating that ccall is “discouraged”. The article doesn’t mention why that is, and googling “ccall discouraged” yields no good results.

I’ve tried replacing ccall with capi, since that’s all there is to do apparenly, but it didn’t work completely, since wrapper isn’t supported. So two questions:

  1. Why is ccall discouraged?
  2. What do I do to replace wrapper in capi?
1 Like

This blog post from Ben talks about ccall vs capi: Best practices for foreign imports - Well-Typed: The Haskell Consultants

And here’s a bit more detail about the wrapper situation: #21532: "foreign import capi" causes panic with sqlite · Issues · Glasgow Haskell Compiler / GHC · GitLab

The bottom line is that capi allows the compiler to check the calling convention and prevents various bugs compared to ccall, which relies more on the FFI bindings being written correctly. But ccall has advantages in some cases (including the ability to use wrapper), and it isn’t going anywhere. So you may wish to stick with ccall. You might be able to use foreign exports instead of wrapper, but that requires that all the Haskell computations being passed to C code are known in advance.

3 Likes

Ah, thanks for the articles, that helps!

Can I mix both? Use wrappers and ccall for cases where I have a FunPtr and capi otherwise?

Yes - I am doing that for botan, and it is working quite nicely.

1 Like