
On 26 Jun 2015 at 10:42, Andrzej Krzemienski wrote:
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).
To what run-time condition does an empty state correspond here? I used to thing that you either have a result (T) or a reason why you do not have one (error_code), but what does it mean that you have neither?
From a non-semantic perspective, avoiding exception_ptr has *BIG* benefits to runtime overhead because exception_ptr forces a memory barrier, which is why MSVC spews ~2000 opcodes every time you use it. Some of the time in promise-future you really don't require the ability to transport arbitrary exceptions because an error_code is enough, or maybe even no error transport is needed at all. Why
Semantically speaking, after feedback from this list, and having attended Charley's C++ Now Presentation on ternary logic programming "Your CPU is Binary", I realised that it's worthwhile to formally specify future/monad/result as ternary logic primitives with ternary logic operators. option<T> remains boolean. This gives the following logic table: Empty => False (future/monad/result/option) Errored/Excepted => Indeterminate (future/monad/result) Value => True (future/monad/result/option) In other words, you never draw a distinction between errored and excepted. They are semantically equivalent. Therefore not being possible to be excepted in the case of result<T> means nothing, it's simply a quality of implementation detail. therefore pay for an exception transport when you don't need it? In AFIO any time we go near OS APIs we currently convert the system error code into an exception and throw it - this is total overkill. Using result<T>, any time AFIO calls OS APIs it can exactly and precisely wrap the outcome into a result<T> and not expend overhead on unnecessary exception_ptr costs. Only if downstream code consumes the result without checking for an error will a lazy conversion to an exception throw occur. This is why I hope these lightweight promise-futures will be lightweight enough to promise-future a SHA256 round inside a budget of 40 cycles because you can disable all error transport entirely, and effectively just promise an async_optional<char[32]> as SHA256 cannot generate errors. Compare that to std::promise/future which costs >= 530 CPU cycles per round, a little more than the SHA256 round itself. I'm still unsure how to handle naming though. promise<T>/future<T> obviously mean what they mean under the Concurrency TS, so they must support exception_ptr. A promise-future only capable of transporting a T and nothing else would need a descriptive name. I'm currently thinking promise_option<T> and future_option<T>, but I (a) find those too verbose and (b) I don't think the name means what they do precisely. Any suggestions for a better name for a kind of future which can only transport a T and nothing else is welcome. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/