Use the following invoke combinator to apply a function to a value in another (forked) process and then block waiting for its result when the () value is applied:
let invoke (f :'a ->'b) x : unit ->'b =let input, output = Unix.pipe()inmatch Unix.fork()with|-1->(let v = f x infun()-> v)|0->
Unix.close input;let output = Unix.out_channel_of_descr output in
Marshal.to_channel output (try`Res(f x)with e ->`Exn e);
exit 0| pid ->
Unix.close output;let input = Unix.in_channel_of_descr input infun()->let v = Marshal.from_channel input in
ignore (Unix.waitpid  pid);
close_in input;match v with|`Res x -> x
|`Exn e -> raise e
OCaml is the only functional language with bindings in the LLVM distro itself and documentation on llvm.org such as the Kaleidoscope tutorial. If you have OCaml installed when you build and install LLVM then it will automatically build and install the LLVM bindings for OCaml as well. Moreover, these OCaml bindings have been in use for years so they are mature and reliable.
Jacques Garrigue already implemented a syntactically-light but inefficient approach for many data structures several years ago. You just wrap the collections in objects that provide a map method. Then you can do collection#map to use the map function for any kind of collection. This is general because it allows different kinds of data structures to be substituted at run time. However, this is not very useful in practice so the approach was never widely adopted.