$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: [boost] Final lightweight monad, next gen futures and upcoming AFIO review (was: Re: [next gen futures] Lightweight monad ready
From: Niall Douglas (s_sourceforge_at_[hidden])
Date: 2015-06-25 21:11:05
On 22 Jun 2015 at 1:43, Niall Douglas wrote:
> Firstly Vicente your three emails contained a ton of gold quality 
> observations. From those I have generated this task list:
> [snip]
> Thank you *hugely* for your feedback Vicente. It was extremely 
> valuable to me.
For those interested, the final version of lightweight monad hit 
github earlier today. Highlights:
monad is now space optimal, consuming as little as two bytes 
depending on configuration. monad<void> is now working, plus these 
new specialisations were added:
* result<T>: empty/T/error_code (no exception_ptr).
* option<T>: empty/T (no error code nor exceptions).
I chose those names to match the same thing in Rust. They are all 
really instantiations of basic_monad<> with a different policy class. 
As will be lightweight future<T> next week.
I formalised the logic behind monad into a tribool based ternary 
logic, with added C++ 11 tribool implementation based on a constexpr 
enum class. This provides a full ternary logic via the usual AND OR 
operators etc such that:
if(true_(monad))  // has value
  ...
else if(false_(monad))  // is empty
 ...
else // if(other(monad)) // is errored or excepted
 ...
One can now do make_monad([](Args...){}) and the monad can be called 
with (Args...). That also applies to result and option. This opens 
some very interesting possibilities for lazy functional programming.
Finally, I added some operator overloads. The bind operator is now 
shortcut with operator >>, and operator | and & can be used for 
expression binds instead of functional binds like this:
    std::error_code ec;
    monad<int> a(5);
    monad<int> b(a & 6);   // a has a value, so become 6
    monad<int> c(b | 4);   // b has a value, so remain at 6
    monad<int> d(a & ec);  // a has a value, so become errored
    monad<int> e(d & 2);   // d does not have a value, so remain 
errored
    monad<int> f(d | 2);   // d does not have a value, so become 2
I believe, sans bugs, lightweight monad is now finished. I have some 
minor todo items, but this is my final intended feature set. Build 
impact remains featherweight, space impact is close to optimally low, 
and I have even shaved off a few more opcodes from what the compiler 
generates for all the operations.
This weekend I'll get started on lightweight future-promise which 
derives from monad and indeed is also a basic_monad but with 
different implementation policy class. These future-promise ought to 
be 98% compatible with the WG21 Concurrency TS spec and will be able 
to participate in hetereogeneous when_any/when_all i.e. you can mash 
them in with std::future.
It'll likely take me a week to come up with some benchmarks comparing 
std::future and my future in a 4-SHA256 engine so you can see the 
benefits of the new design. After that I'll replace AFIO's 
std::future with these lightweight futures in its public API, and we 
should be ready to rock for the 17th July when AFIO's review begins.
Note that only the public user facing API will be refactored to use 
these lightweight futures such that you all will review my best 
attempt at a final and stable API. I'll leave the existing internal 
engine well alone as it's mature and stable until after the community 
review, as it will have to be completely redesigned and rewritten to 
have optimal performance with these new futures. I don't expect that 
to be at all noticeable from external code however, it'll just go 
much faster, that's all.
Niall
-- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/