ned Productions Consulting

Technology musings by Niall Douglas
ned Productions Consulting
(an expert advice and services company based in Ireland)

Friday 12th June 2015 12.12pm

As some may know, I've been working on the world's simplest C++ runtime monad these past two weeks, where most of that effort is being spent on getting it to STL quality with a full conformance and validation unit test suite. The hope is that this will become the official Boost monad, and thereafter the monad proposed for standardisation. Unlike any other C++ monad that I am aware of, this design focuses on:

(i) Absolute minimum possible impact on build times and especially runtime overhead. No memory allocation, not ever.
(ii) Deep integration with forthcoming lightweight future-promise which are essentially just async monads and are similarly lightweight to these monads.
(iii) Deliberate design impurity to make it natural and obvious for C++ programmers to use.

The latter feature may worry Haskell purists, so I'll clarify: by impure I mean that the lightweight monad is fixed variant, so in a monad<T> you get either a T, an error_code, an exception_ptr or empty i.e. it's a four state monad, which is of course not a proper monad but it does get you an optional<T> replacement for free. I also ended up calling it a monad<T>, which no monad would ever be called (maybe, result etc etc anything but monad) as per the C++ tradition of bastardising implementations of pure features from other languages.

It'll probably go to boost-dev for community feedback early next week, but to give you a taster, I can guarantee the following runtime overheads when using it:

* Space cost of max(20, sizeof(T)+4)

* state known/state unknown x64 opcodes generated:

  * clang 3.7
  59 opcodes <= Value transport <= 37 opcodes
  7 opcodes <= Error transport <= 52 opcodes
  38 opcodes <= Exception transport <= 39 opcodes

  * GCC 5.1
  1 opcodes <= Value transport <= 113 opcodes
  8 opcodes <= Error transport <= 119 opcodes
  22 opcodes <= Exception transport <= 214 opcodes

  * VS2015
  4 opcodes <= Value transport <= 1881 opcodes
  6 opcodes <= Error transport <= 164 opcodes
  1946 opcodes <= Exception transport <= 1936 opcodes

And by guarantee, I really mean guarantee. Those guarantees are empirically tested per commit by the CI by compiling a list of use cases and counting the assembler ops generated by the compiler. If the count exceeds a limit, the commit is failed.

If you like the Result<T> from Rust and have gotten used to writing code using that design, if this monad is accepted by Boost you'll have pretty much the same thing, except even easier to program with and even more lightweight than Rust's Result<T>!

Watch this space for when this monad gets sent for review!