# inline-c `inline-c` lets you seamlessly call C libraries and embed high-performance inline C code in Haskell modules. Haskell and C can be freely intermixed in the same source file, and data passed to and from code in either language with minimal overhead. No FFI required. `inline-c` is Haskell's escape hatch (or one of) to the wild world of legacy code and high-performance numerical and system libraries. It has other uses too: you can also think of `inline-c` as to Haskell what inline Assembly is to C — a convenient means to eke out a little bit of extra performance in those rare cases where C still beats Haskell. GHCi support is currently limited to using `-fobject-code`, see the [last section](#ghci) for more info. ## Getting started Let's say we want to compute the cosine of a number using C from Haskell. `inline-c` lets you write this function call inline, without any need for a binding to the foreign function: ``` {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE TemplateHaskell #-} import qualified Language.C.Inline as C C.include "" main :: IO () main = do x <- [C.exp| double{ cos(1) } |] print x ``` `inline-c` leverages the [quasiquotation][ghc-manual-quasiquotation] language extension implemented in GHC. [Template Haskell][ghc-manual-template-haskell] is also required. Importing the `Language.C.Inline` module brings in scope most required Haskell definitions. `C.include ""` brings into scope the foreign function `cos()` that we wish to call. Finally, in the `main` function, `[C.exp| double { cos(1) } |]` denotes an inline C expression of type `double`. `cexp` stands for "C expression". It is a custom quasiquoter provided by `inline-c`. A `C.exp` quasiquotation always includes a type annotation for the inline C expression. This annotation determines the type of the quasiquotation in Haskell. Out of the box, `inline-c` knows how to map many common C types to Haskell types. In this case, ``` [C.exp| double { cos(1) } |] :: IO CDouble ``` For pure C expression like these we also provide `C.pure`, which works exactly the same but without the `IO`: ``` [C.pure| double { cos(1) } |] :: CDouble ``` Obviously extra care must be taken when using `C.pure`: the embedded C code must be referentially transparent. ## Multiple statements `inline-c` allows embedding arbitrary C code, not just expressions, in the form of a sequence of statements, using the `c` quasiquoter: ``` {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE TemplateHaskell #-} import qualified Language.C.Inline as C C.include "" main :: IO () main = do x <- [C.block| int { // Read and sum 5 integers int i, sum = 0, tmp; for (i = 0; i < 5; i++) { scanf("%d", &tmp); sum += tmp; } return sum; } |] print x ``` Just as with `C.exp`, we need a type annotation on the entire C block. The annotation specifies the return type. That is, the type of the expression in any return statement. ## Capturing Haskell variables -- parameter declaration `inline-c` allows referring to Haskell variables inside C expressions and code blocks. We do so by "anti-quoting" them. Let's say that we wanted to parameterize the function we wrote above by how many numbers we should read. We can do so by defining a Haskell function whose parameter we can refer to from within C: ``` {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE TemplateHaskell #-} import qualified Language.C.Inline as C import Foreign.C.Types C.include "" -- | @readAndSum n@ reads @n@ numbers from standard input and returns -- their sum. readAndSum :: CInt -> IO CInt readAndSum n = [C.block| int { // Read and sum n integers int i, sum = 0, tmp; for (i = 0; i < $(int n); i++) { scanf("%d", &tmp); sum += tmp; } return sum; } |] main :: IO () main = do x <- readAndSum 5 print x ``` Here, the Haskell variable `n` is captured right where we need it using `$(int n)`. Standard anti-quotation (we'll talk about additional ones later) consists of a `$` followed by a C declaration in parenthesis. Note that any valid Haskell identifiers can be used when anti-quoting, including ones including constructors, qualified names, names containing unicode, etc. For each anti-quotation, a variable with a matching type is expected in the Haskell environment. In this case `inline-c` expects a variable named `n` of type `CInt`, which is the case. ## What can be captured and returned? All C types correspond to exactly one Haskell type. Basic types (`int`, `long`, `double`, `float`, etc.) get converted to their Haskell equivalents `CInt`, `CLong`, `CDouble`, `CFloat`. Pointers and arrays get converted to `Ptr`. Function pointers get converted to `FunPtr`. `inline-c` can also handle user-defined structs and enums, provided that they are instances of `Storable` and that you tell `inline-c` about them using [contexts](#contexts). ## Contexts Everything beyond the base functionality provided by `inline-c` is specified in a structure that we call "`Context`". From a user perspective, if we want to use anything but the default context (`C.baseCtx`), we must set the `C.Context` explicitly using the `C.context` function. The next two sections include several examples. The `C.Context` allows to extend `inline-c` to support * Custom C types beyond the basic ones; * And [additional anti-quoters](#more-anti-quoters). `C.Context`s can be composed using their `Monoid` instance. Ideally a `C.Context` will be provided for each C library that should be used with `inline-c`. The user can then combine multiple contexts together if multiple libraries are to be used in the same program. See the [`inline-c-nag` package](https://github.com/fpco/inline-c-nag) for an example of using a `C.Context` tailored for a library. For information regarding how to define `C.Context`s, see the Haddock-generated API documentation for `Language.C.Inline.Context`. ## More anti-quoters Besides the basic anti-quoter, which captures variables as they are, some more anti-quoters are provided with additional functionality. As mentioned, `inline-c` can easily be extended with anti-quoters defined by the user, using [contexts](#contexts). ### Vectors The `vec-len` and `vec-ptr` anti-quoters in the `C.vecCtx` context let us easily use [Haskell vectors](http://hackage.haskell.org/package/vector) in C. Continuing along the "summing" theme, we can write code that sums Haskell vectors in C: ``` {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE TemplateHaskell #-} import qualified Language.C.Inline as C import qualified Data.Vector.Storable as V import qualified Data.Vector.Storable.Mutable as VM import Data.Monoid ((<>)) import Foreign.C.Types -- To use the vector anti-quoters, we need the 'C.vecCtx' along with the -- 'C.baseCtx'. C.context (C.baseCtx <> C.vecCtx) sumVec :: VM.IOVector CDouble -> IO CDouble sumVec vec = [C.block| double { double sum = 0; int i; for (i = 0; i < $vec-len:vec; i++) { sum += $vec-ptr:(double *vec)[i]; } return sum; } |] main :: IO () main = do x <- sumVec =<< V.thaw (V.fromList [1,2,3]) print x ``` The `vec-len` anti-quoter is used simply by specifying the vector we want to get the length of (in our case, `vec`). To use the `vec-ptr` anti-quoter it is also required to specify the pointer type we want. Since `vec` is a vector of `CDouble`s, we want a pointer to `double`s. ## ByteStrings The `bs-len` and `bs-ptr` anti-quoters in the `C.bsCtx` context work exactly the same as the `vec-len` and `vec-ptr` counterparts, but with strict `ByteString`s. The only difference is that it is not necessary to specify the type of the pointer from C -- it is always going to be `char *`: ``` {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE QuasiQuotes #-} import qualified Data.ByteString as BS import Data.Monoid ((<>)) import Foreign.C.Types import qualified Language.C.Inline as C C.context (C.baseCtx <> C.bsCtx) -- | Count the number of set bits in a 'BS.ByteString'. countSetBits :: BS.ByteString -> IO CInt countSetBits bs = [C.block| int { int i, bits = 0; for (i = 0; i < $bs-len:bs; i++) { char ch = $bs-ptr:bs[i]; bits += (ch * 01001001001ULL & 042104210421ULL) % 017; } return bits; } |] ``` ### Function pointers Using the `fun` anti-quoter, present in the `C.funCtx` context, we can easily turn Haskell function into function pointers. ``` {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE TemplateHaskell #-} import qualified Language.C.Inline as C -- To use the function pointer anti-quoter, we need the 'C.funCtx' along with -- the 'C.baseCtx'. C.context (C.baseCtx <> C.funCtx) ackermann :: CLong -> CLong -> CLong ackermann m n | m == 0 = n + 1 | m > 0 && n == 0 = ackermann (m - 1) 1 | otherwise = ackermann (m - 1) (ackermann m (n - 1)) main :: IO () main = do let ackermannIO m n = return $ ackermann m n let x = 3 let y = 4 z <- [C.exp| long{ $fun:(long (*ackermannIO)(long, long))($(long x), $(long y)) } |] print z ``` In this example, we capture a Haskell function of type `CLong -> CLong -> IO CLong`, `ackermannIO`, to a function pointer in C, using the `fun` anti-quoter. Note how we need to specify the function pointer type when we capture `ackermannIO`, using standard C declaration syntax. Also note that the `fun` anti-quoter works with `IO` functions, and so we needed to modify `ackermann` to make it have the right type. In general, when anti-quoting, if the type can be inferred (like in the case of `vec-len`), only the Haskell identifier appears. If it can't, the target C type and the Haskell identifier are mentioned using C declaration syntax. ## GHCi Currently `inline-c` does not work in interpreted mode. However, GHCi can still be used using the `-fobject-code` flag. For speed, we recommend passing `-fobject-code -O0`, for example ``` stack ghci --ghci-options='-fobject-code -O0' ``` or ``` cabal repl --ghc-options='-fobject-code -O0' ``` [ghc-manual-quasiquotation]: https://downloads.haskell.org/ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell-quasi-quotation [ghc-manual-template-haskell]: https://downloads.haskell.org/ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell