packages feed

inline-c-0.5.2.0: README.md

# inline-c

[![Build Status](https://travis-ci.org/fpco/inline-c.svg)](https://travis-ci.org/fpco/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.

Build instructions are reserved for the [last section](#how-to-build).
You'll need to compile the examples below and try them out.

## Getting started

Let's say we want to compute the cosine of a number using C from
Haskell. `inline-c` let's 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 "<math.h>"

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 "<math.h>"` 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 type. 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 "<stdio.h>"

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 "<stdio.h>"

-- | @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.

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.Mutable as V
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 :: V.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.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` ant-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 no necessary to
specify the type of the pointer from C -- it is always going to be
`unsigned 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++) {
        unsigned 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:(int (*ackermannIO)(int, int))($(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.

## How to build

Each module that uses at least one of the `inline-c` functions gets a C
file associated to it, where the filename of said file will be the same
as the module but with a C extension.  This C file must be built after
the Haskell code and linked appropriately.  If you use cabal, all you
have to do is declare each associated C file in the `.cabal` file and
you are good.

For example we might have

```
executable foo
  main-is:             Main.hs, Foo.hs, Bar.hs
  hs-source-dirs:      src
  -- Here the corresponding C sources must be listed for every module
  -- that uses C code.  In this example, Main.hs and Bar.hs do, but
  -- Foo.hs does not.
  c-sources:           src/Main.c, src/Bar.c
  -- These flags will be passed to the C compiler
  cc-options:          -Wall -O2
  -- Libraries to link the code with.
  extra-libraries:     -lm
  ...
```

Note that currently `cabal repl` is not supported, because the C code is
not compiled and linked appropriately.  Type-checking will still be
performed, so `cabal repl` can still be used to develop.

See `sample-cabal-project` for a working example.

If we were to compile the above manually we could do:

```
$ ghc -c Main.hs
$ cc -c Main.c -o Main_c.o
$ ghc Foo.hs
$ ghc Bar.hs
$ cc -c Bar.c -o Bar_c.o
$ ghc Main.o Foo.o Bar.o Main_c.o Bar_c.o -lm -o Main
```

[ghc-manual-quasiquotation]:
https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/template-haskell.html#th-quasiquotation
[ghc-manual-template-haskell]: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/template-haskell.html