OCamlPro Highlights: May-June 2014
Here is a short report on some of our public activities in May and June 2014.
Towards OPAM 1.2
After a lot of discussions and work on OPAM itself, we are now getting to a clear workflow for OCaml developpers and packagers: the preliminary document for OPAM 1.2 is available here. The idea is that you can now easily create and test the metadata locally, before having to get your package included in any repo: there is less administrative burden and it's much quicker to start, fix it, test it and get it right.
Things getting pretty stable, we are closing the last few bugs and should be releasing 1.2~beta very shortly.
OCaml Hacking Session
We participated in the first OCaml hacking session in Paris organized by Thomas Braibant and supervised by Gabriel Scherer, who had kindly prepared in advance a selection of tasks. In particular, he came with a list of open bugs in Mantis that makes for good first descents in the compiler's code.
It was the first event of this kind for the OCaml Users in Paris (OUPS) meetup group. It was a success since everybody enjoyed it and some work has actually been achieved. We'll have to wait for the next one to confirm that !
On our front, Fabrice started working (with others) on a good, consensual Emacs profile; Pierre worked on building cross-compilers using Makefile templates; Benjamin wanted to evaluate the feasibility of handling ppx extension nodes correctly inside Emacs, and it turns out that elisp tools exist for the task! You can see a first experiment running in the following screen capture, or even try the code (just open it in emacs, do a
M-x eval-buffer on it and then a
M-x tuareg-mode-with-ppx on an OCaml file). But beware, it's not yet very mainstream and can make your Emacs crash.
During the last two months, we participated in the supervision of an intern, Albin Coquereau - a graduted student at University Paris-Sud - in the VALS team who worked on a conservative extension of the SMT2 standard input language with prenex polymorphism a la ML and overloading. First results are promising. In the future, we plan to replace Alt-Ergo's input language with our extension of SMT2 in order to get advantage from SMT2's features and polymorphism's expressiveness.
OCaml Adventures in Scilab Land
We are currently working on the proper integration of our Scilab tools in the Scilab world, respecting its ways and conventions. For this, we built a Scilab module respecting the standard ATOMS interface. This module can embed an OCaml program inside the run-time environment of Scilab, so that OCaml functions can be called as external primitives. (Dyn)linking Scilab's various components, LLVM's and the OCaml run-time together was not that easy.
Symmetrically, we built an OCaml library to manipulate and build Scilab values from OCaml, so that our tools can introspect the dynamic envrionment of Scilab's interprete. We also worked with the Scilab team to defined an AST interchange mechanism.
We plan to use this module as an entry point for our JIT oriented type system, as well as to integrate Scilint, our style checker, so that a Scilab user can check their functions without leaving the Scilab toplevel.
Experiment with Bytes and Backward Compatibility
As announced by a long discussion in the caml-list, OCaml 4.02 introduces the first step to eliminate a long known OCaml problem: String Mutability. The main difficulty being that resolving that problem necessarilly breaks backward compatibility.
To achieve this first step, OCaml 4.02 comes with a new
bytes type and a corresponding
Bytes module, similar to OCaml 4.01
String module, but using the
bytes type. The type of a few functions from the
String module changed to use the
bytes type (like
String.blit... ). By default the
bytes types are equal, hence ensuring backward compatibility for this release, but a new argument "
-safe-string" to the compiler can be used to remove this equality, and will probably become the default in some future release.
# let s = "foo";; val s : string = "foo" # s. <- 'a';; Characters 0-1: s. <- 'a';; ^ Error: This expression has type string but an expression was expected of type bytes
Notice that even when using
-safe-string you shouldn't rely on strings being immutable. For instance even if you compile that file with
-safe-string, the assertion in the function
g does not necessarilly hold:
If the following file
a.ml is compiled with
let s = "foo" let f () = s let g () = assert(s = "foo")
and the following file
b.ml is compiled without -safe-string
let s = A.f () in s. <- 'a'; A.g ()
b.ml the equality holds, so modifying the string is possible, and the assertion from
A.g will fail.
So you should consider that for now
-safe-string is only a compiler-enforced good practice. But this may (and should) change in future versions. The
ocamlc man page says:
-safe-string Enforce the separation between types string and bytes, thereby making strings read-only. This will become the default in a future version of OCaml.
In other words if you want your current code to be forward-compatible, your code should start using
bytes instead of
string as soon as possible.
Maintaining Compatibility between 4.01 and 4.02
In our experiments, we found a convenient solution to start using the
bytes type while still providing compatibility with 4.01: we use a small
StringCompat module that we open at the beginning of all our files making use of
bytes. Depending on the version of OCaml used to build the program, we provide two different implementations of
- Before 4.02, our
stringCompat.mlfile provides a
bytestype and a
Bytesmodule, including the
Stringmodule plus an often used
type bytes = string module Bytes = struct include String let to_string t = t end
- After 4.02, our
stringCompat.mlfile is much simpler:
type t = bytes type bytes = t module Bytes = Bytes
You might actually even wonder why it is not empty ? In fact, it is also a good practice to compile with a warning for unused
open, and an empty
stringCompat.ml would always trigger a warning in 4.02 for not being useful. Instead, this simple implementation is always seen as useful, as any use of
Bytes will use the (virtual) indirection through
We plan to upload this module as a
string-compat package in OPAM, so that everybody can use this trick. If you have a better solution, we'll be pleased to discuss it via the pull on
Testing whether your project correctly builds with "-safe-string"
When your code have been adapted to use the bytes whenever you need to modify a string, you can test if you didn't miss a case using OCaml 4.02 without changing your build system. To do that, you can just set the environment variable
"safe-string=1,_". Notice that "
OCAMLPARAM" should only be used for testing purpose, never set it in your build system or tools, this would prevent testing new compiler options on your package (and you will receive complaints when the core developers can't desactivate the
"-w A -warn-error" generated by your build system) !
If your project passes this test and you don't use
"-warn-error", your package should continue to build without modification in the near and the not-so-near future (unless you link with the compiler internals of course).
OCamlPro is a R&D lab founded in 2011, with the mission to help industrial users benefit from state-of-the art programming languages like OCaml and Rust.
We design, create and implement custom ad-hoc software for our clients. We also have a long experience in developing and maintaining open-source tooling for OCaml, such as Opam, TryOCaml, ocp-indent, ocp-index and ocp-browser, and we contribute to the core-development of OCaml, notably with our work on the Flambda optimizer branch.
Another area of expertise is that of Formal Methods, with tools such as our SMT Solver Alt-Ergo (check our Alt-Ergo Users'). We also provide vocational trainings in OCaml and Rust, and we can build courses on formal methods on-demand. Please reach out, we'll be delighted to discuss your challenges: firstname.lastname@example.org or book a quick discussion.