OCaml Weekly News
Hello
Here is the latest OCaml Weekly News, for the week of April 23 to 30, 2019.
Table of Contents
FYI: Writing Network Drivers in High-Level Languages
Oliver Bandel announced
Writing Network Drivers in High-Level Languages How to write drivers in Rust, go, C#, Swift, Haskell, and OCaml https://fosdem.org/2019/schedule/event/writing_network_drivers_in_high_level_languages/
Treiber in High-Level Programmiersprachen https://media.ccc.de/v/eh19-189-treiber-in-high-level-programmiersprachen
orewa 0.1.0, a redis binding (initial release)
Marek Kubica announced
For a while I was frustrated by the somewhat lacking state of Redis support in OCaml especially when it comes to supporting Async so I decided to reinvent the wheel again and see how a binding to Redis would look like if it was designed with non-blocking execution in focus.
The result is Orewa, which I have released as 0.1.0
recently. So far it supports most or even all of the Redis 5.0 string operations and a somewhat randomly picked set of other instructions.
There are a couple of considerations I had when building it:
- Be non-blocking first. It supports Async for now since that is what I use and what is lacking the most in the current ecosystem. I tried to be thread-safe, we'll see if I was successful in doing so.
- Avoid exceptions to avoid unwanted surprises.
- Have a somewhat typesafe API. The Redis protocol is mostly stringly-typed and this binding tries to wrap this into a bit of a more typed interface:
- No distinction between millisecond and second resolution commands, you specify the duration as a timespan and
Orewa
does the rest - The results are parsed into the expected data type if possible
- The arguments try to reduce the possible misuse. There is still some misuse possible, so this current release tries to strike a balance of typing vs similarity with the Redis documentation
- No distinction between millisecond and second resolution commands, you specify the duration as a timespan and
The documentation is on GitHub and it is installable from OPAM.
Unicode support improvements in zed, lambda-term and utop
ZAN DoYe announced
We are working on improving unicode support in zed, lambda-term and utop.
These new improvements retrofit the concept of what the essential element should be, from UChar.t, an individual unicode character to Zed_char.t, a new type representing a glyph in the unicode standard. So non-latin script and combined glyphes will be better supported.
For more information and the preview releases of these projects, see https://github.com/ocaml-community/lambda-term/issues/2#issuecomment-487348878
initial release of ppx_cstubs
fdopen announced
It is my pleasure to announce the first release of ppx_cstubs!
ppx_cstubs is ppx-based preprocessor for quick and dirty stub generation with ctypes. It creates two files from a single OCaml file: a file with c stub code and a ml file with all additional boilerplate code.
The preprocessor abuses external
declarations that are not used in regular code. Instead of OCaml types, values of type Ctypes.typ are used inside the declarations:
/* function prototypes */ int puts(const char *s); char *getenv(const char *name);
To access the functions above from OCaml, you simply repeat the prototype in OCaml syntax and with appropriate Ctypes.typ
values:
external puts: string -> int = "puts" external getenv: string -> string_opt = "getenv" let () = (* regular code *) match getenv "HOME" with | None -> () | Some s -> let i = puts s in ...
As a slight extension of the scheme above, you can also label your parameters, annotate external (%c
) and write a few lines of C code:
external%c flush_printf : str:string -> i64:int64_t -> bool = {| int r = printf("first param:%s; second param:%" PRId64 "\n", $str, $i64); if ( r < 0 ) { return false; } r = fflush(stdout); return (r == 0); /* `return` is mandatory, unless your function is void */ |} [@@ release_runtime_lock] /* other possible attributes are [@@ noalloc] and [@@ return_errno] */ let () = let r : bool = flush_printf ~str:"Hello World" ~i64:4L in ...
This way several switches between the OCaml runtime and C are avoided. This has various advantages:
- Intermediate results can be stored on the C stack. They don't need to be allocated on the heap and wrapped in a way to appease the OCaml runtime.
- the c compiler can better optimise your code.
- constant parameters don't need to exposed to OCaml, just to pass them to the C function.
- you often have to write (and generate) less code, if you don't create wrappers for every c function and type, but just wrap snippets of C code.
Further possibilities, examples, and limitations are described in the project's README.
Dune, cross compilation, and Raspberry Pi
Yaron Minsky asked
I'm thinking of doing some home projects for doing stuff like driving LEDs from a Raspberry Pi using OCaml. Is there a good way of doing this with a cross compiler via OCaml? Or do I need to install OCaml and build my executables on the Pi? I know that there was some work to get cross compilation working properly with Dune, but I don't know how to do it in practice.
Nicolás Ojeda Bär replied
Not exactly your question, but you may be interested in https://github.com/dbuenzli/rpi-boot-ocaml
Jérémie Dimino also replied
Currently, the cross compilation story with dune is as follow: once you have setup one of the cross-compiling environments available on https://github.com/ocaml-cross, you can cross-compile with dune as follow:
$ dune build -x windows,android,ios ...
This will create _build/default.windows
, _build/default.android
and so on.
The longest step is building/installing the cross-compiler. You don't need a special dune to cross compile.
Anil Madhavapeddy also replied
If you're working on a Mac/Win, then a cheap and cheerful way to get an rPI-compatible environment is to use Docker for Mac/Win, which transparently do CPU emulation via qemu-user-static
and binfmt.
$ docker run -it ocaml/opam2-staging:debian-9-ocaml-4.08-linux-arm32v7 opam@fdd0cc1ae238:~/opam-repository$ uname -a Linux fdd0cc1ae238 4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018 armv7l GNU/Linux opam@fdd0cc1ae238:~/opam-repository$ ocamlc -config|grep arch architecture: arm opam@fdd0cc1ae238:~/opam-repository$ opam install -y dune <...etc>
You can save the binary results of the build by adding a -v <yourrepo>:/home/opam/src
to mount a local volume within the ARM container. This will be a pretty slow option, but probably faster than compiling within the rPi3.
Searching for functions
Continuing this thread, gndl said
Even if the project looks asleep, it may be interesting to mention it here : https://github.com/camlspotter/ocamloscope.2.
Frédéric Bour also said
Merlin has a search feature, :MerlinSearch
in vim or M-x merlin-search
in emacs.
The command takes a query which is a list of type names prefixed by -
or +
:
-
for the type of values you have and the function you are looking for can consume+
for values you would like to get.
For instance, :MerlinSearch -int +string
gives you ways to transform an integer to a string:
string_of_int V int -> string Bytes.create V int -> bytes BytesLabels.create V int -> bytes String.create V int -> bytes StringLabels.create V int -> bytes Big_int.approx_big_int V int -> Big_int.big_int -> string Num.approx_num_exp V int -> Num.num -> string Num.approx_num_fix V int -> Num.num -> string Ratio.approx_ratio_exp V int -> Ratio.ratio -> string Ratio.approx_ratio_fix V int -> Ratio.ratio -> string ...
Parametric types are flattened (only variance is considered), so String.concat
can be found with -string -list +string
. I haven't thought about filtering based on the name of values, but this should be easy to implement in a future version of merlin, e.g. env -string +string
for finding string transformers that contains "env" in their name.
The UI has not seen much work and the search is blocking, which is not super convenient, help is welcome to improve that :).
UnixJunkie then asked and Frédéric Bour replied
> Does it search through all the opam-installed libraries? Or just the currently opened project?
It searches only in the project scope. This is a proof-of-concept, but it can easily be enhanced to do opam-wide search (I didn't think about it because that I never felt the need). Also, the search space can easily be indexed (while right now it is doing linear search), so performance should not be a problem at scale. I need to talk to @dbuenzli about that :).
> Why not support plain type signatures like int -> string, why do you need the - and +?
With the current spec, the search is directed by variance which more accurately reflects the flow of information than a mere ->
. If it is just about syntax, of course the query language can be reworked, it is just frontend work (similarly, Hoogle does not strictly search by signature and do some approximation).
By relying only on variance, values are found even if they execute in a different monad, are written in a continuation passing-style or need more contexts (e.g. a context value). Results can then be ranked by relevance (though that bit has subjective elements in it).
Other OCaml News
From the ocamlcore planet blog
Here are links from many OCaml blogs aggregated at OCaml Planet.
Old CWN
If you happen to miss a CWN, you can send me a message and I'll mail it to you, or go take a look at the archive or the RSS feed of the archives.
If you also wish to receive it every week by mail, you may subscribe online.