My lightweight very simple single purpose monad has been sent to boost-dev for community feedback http://boost.2283326.n4.nabble.com/next-gen-futures-Lightweight-monad-ready-for-inspection-td4677322.html.
This monad can hold a fixed variant list of empty, a type R, a lightweight error_type or a heavier exception_type at a space cost of max(20, sizeof(R)+4). Features:
* Very lightweight on build times and run times up to the point of zero execution cost and just a four byte space overhead. Requires min clang 3.2, GCC 4.7 or VS2015. A quick sample of runtime overhead, min to max opcodes generated by GCC 5.1:
1 opcodes <= Value transport <= 113 opcodes
8 opcodes <= Error transport <= 119 opcodes
22 opcodes <= Exception transport <= 214 opcodes
4 opcodes <= then() <= 154 opcodes
5 opcodes <= bind() <= 44 opcodes
* Just enough monad, nothing more, nothing fancy. Replicates the future API with a fair chunk of the Expected<T> API, so if you know how to use a future you already know how to use this.
* Enables convenient all-noexcept mathematically verifiable close semantic design, so why bother with Rust anymore? :)
* Can replace most uses of optional<T>.
* Deep integration with lightweight future-promise (i.e. async monadic programming) also in this library.
* Comprehensive unit testing and validation suite.
* Mirrors noexcept of type R.
* Type R can have no default constructor, move nor copy.
* Works inside a STL container, and type R can be a STL container.
* No comparison operations nor hashing is provided, deliberately to keep things simple.
Online wandbox compiler:
Any opinions or thoughts gratefully received, particularly if I have the exception safety semantics right (i.e. a throw during move or copy leaves the monad empty). Do you also like the polymorphic bind() and map() which does different things depending on the parameter type your callable takes? Do you like that by simply changing the callable's type to a rvalue reference you can move state, or is this being too clever?
This monad will become the basis of lightweight future-promise which is essentially a "split monad" with the setter interface and getter interface potentially in different system threads. The then(), bind() and map() work as here but only are triggered at the point of the value being changed. This effectively makes the lightweight future a "lazy continued monad".
That lightweight future-promise will then enter AFIO to replace its async_io_op type hopefully in time for the peer review this time next month.
#c++ #c++14 #boostcpp #boostafio