2015-06-19 17:03:59 UTC
l-the-monadic-return-type-td4676039.html and that I would firstly
prepare an optimally lightweight monad<T> for review here before
going on to base a next-gen lightweight future-promise on that
I didn't expect it would take nearly four weeks to get there, but
writing STL quality C++ with full conformance test suite is amazingly
labourious. Anyway you can now view the design and tell me what you
think. A quick overview of the design:
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
ned Productions Limited Consulting