1+++ 2title = "History" 3weight = 90 4+++ 5 6Outcome has had an interesting history, and it is worth summarising it here to show how a 7Boost library comes to life. The following recollections are by Niall Douglas, and may be 8faulty due to his aging memory. 9 10{{<if_boost "/history/graph.png">}} 11{{<mermaid>}} 12gantt 13 dateFormat YYYY-MM 14 title History of the Outcome library 15 Outcome v1: done, des1, 2014-06,2017-05 16 Boost peer review of v1: done, des2, after des1, 30d 17 Outcome v2 (complete redesign based on first review feedback): done, des3, after des2, 2018-01 18 Boost peer review of v2: done, des4, after des3, 30d 19 Outcome v2.1 (changes from second review): active, des5, 2018-03, 2019-04 20 section Events 21 Separated from AFIO v1: crit, done, 2014-06,2d 22 Boost.Expected added: crit, done, 2014-10,2d 23 Boost.Expected replaced with feature complete basic_monad: crit, done, 2015-08,2d 24 Non-allocating future-promise implementation dropped: crit, done, 2016-05,2d 25 C++ 11 support dropped: crit, done, 2016-06,2d 26 Implemented LEWG expected<T, E> using basic_monad: crit, done, 2017-02,2d 27 Outcome v1 replaced with prototype v2 in git repo: crit, done, 2017-07,2d 28 Boost.Outcome generated by script from Outcome repo: crit, done, 2017-10,2d 29 New tutorial finally complete: crit, done, 2017-12,2d 30 Outcome v2.1 feature complete, maturation begins: crit, done, 2018-04,2d 31 Boost.Outcome docs gain BoostDoc theming: crit, done, 2018-12,2d 32 Planned release of v2.1 into Boost 1.70: crit, active, 2019-04,2d 33{{</mermaid>}} 34{{</if_boost>}} 35 36## The genesis of Outcome v1 37 38The git repo began life as a "Boost.Spinlock" in June 2014 hived out of Boost.AFIO v1 where it had existed 39for some time as an internal library. In October 2014 I added in the original prototype 40Boost.Expected reference library as a git submodule, and began developing a non-allocating 41`future<T>`/`promise<T>` as an extension of `expected<T, std::exception_ptr>` as a faster, 42monadic future-promise was something which AFIO v1 sorely needed. 43 44The original prototype Boost.Expected library was a large and very complex beastie. 45I was fortunate to be employed on a contract in late 2014 early 2015 where I saw it deployed at 46scale into an existing large C++ codebase. Expected was really great and powerful, but it absolutely 47murdered compile times in a large C++ codebase, and made LTO effectively infeasible. 48I also found its implementation non-conducive to implementing 49future-promise with it, and so I resolved to implement a much more powerful policy driven 50monad factory which could stamp out everything from an `option<T>` right through to a 51future-promise pair, all using the exact same `basic_monad<>` and therefore all with a full 52monadic programming API, C++ 17 continuations/monadic bind and intelligently convertible into one another. 53Moreover, all this needed to have an absolute minimum impact on compile times and runtime 54overheads, neither of which were strengths of the original prototype Boost.Expected library. 55 56By August 2015 "Boost.Monad" was delivering on all those requirements and then some, but it lacked 57maturity through use in other code. Summer 2015 saw the Boost peer review of AFIO v1 which 58was roundly rejected. After considering the ample review feedback, it was realised that 59[AFIO v2](https://ned14.github.io/llfio/) would be a very different design, one no longer using futures, memory allocation 60nor C++ exceptions. As AFIO v2 was started from scratch and using Outcome heavily from the 61very beginning (every AFIO v2 API returns a `result<T>`), Outcome began to gain bug fixes and 62shed features, with the non-allocating future-promise implementation being dropped in May 632016 and a large chunk of type based metaprogramming being replaced with cleaner variable template metaprogramming 64in June. After CppCon 2016 in September, then began the long process of getting Outcome 65ready for Boost peer review in Q1 2017 which involved a repeated sequence of complete rewrites 66of the tutorial in response to multiple rounds of feedback from the C++ community, with 67at least four complete rewrites currently at the time of writing. 68 69In parallel to all this development on Outcome, Expected went before the LEWG and entered 70the C++ standards track. As the WG21 meetings went by, Expected experienced a period 71of being stripped back and much of the complexity which had so murdered compile and 72link times in 2014-2015 fell away, thus the Expected proposed in P0323R1 ended up landing 73so close to Outcome that in January 2017 it was just a few hours work to implement 74Expected using the core `basic_monad` infrastructure in Outcome. That highly flexible 75policy based design which made monadic future-promise possible made it similarly easy 76to implement a highly conforming Expected, indeed in early 2017 Outcome's Expected was much 77closer to [P0323R1](http://wg21.link/P0323) than any other implementation including the LEWG reference implementation. 78And unlike the LEWG reference implementation, Outcome has had eighteen months of that 79finely tuned patina you only get when a library is in use by other code bases. 80 81In February 2017 it became realised that the userbase really wanted a high quality `expected<T, E>` 82implementation rather than anything similar but not the same which Outcome had invented. 83The only just implemented Expected implementation based on `basic_monad` therefore took 84primacy. The final rewrite of the documentation before peer review submission was one 85which made it look like Outcome was primarily an `expected<T, E>` implementation with a 86few useful extensions like `outcome<T>` and `result<T>`. I was sad to so pivot, but it 87was obvious that Outcome would see far wider popularity and usage as primarily an Expected 88implementation. 89 90Almost three years after its beginning, Outcome v1 finally went before Boost peer review 91in May 2017 which turned into one of the longest and most detailed peer reviews Boost has 92done in recent years, with over 800 pieces of review feedback submitted. It was by consensus 93rejected, [with substantial feedback on what to do instead](https://lists.boost.org/boost-announce/2017/06/0510.php). 94 95## Outcome v2 96 97During the very lengthy peer review, roughly three groups of opinion emerged as to what 98a `value|error` transporting class ought to look like: 99 100<dl> 101<dt><b>1. Lightweight</b></dt> 102<dd>A simple-as-possible <code>T</code> and/or <code>E</code> transport without any 103implementation complexity.</dd> 104<dt><b>2. Medium</b></dt> 105<dd>A variant stored <code>T</code> or <code>E1</code> ... <code>E<i>n</i></code> 106where <code>T</code> is the expected value and <code>E1 ...</code> 107are the potential unexpected values. This implemention really ought to be implemented 108using C++ 17's <code>std::variant<...></code> except with stronger never-empty guarantees. 109</dd> 110<dt><b>3. Heavy</b></dt> 111<dd>A full fat Either monad participating fully in a wider monadic programming framework for C++.</dd> 112</dl> 113 114Peter Dimov was very quickly able to implement an `expected<T, E1, ...>` using his 115[variant2](https://github.com/pdimov/variant2) library, and thus there seemed little 116point in replicating his work in an Outcome v2. The lightweight choice seemed to be the 117best path forwards, so in June 2017 the bare minimum `result<T, E>` and `outcome<T, EC, P>` 118as presented in this library was built, using the same constructor design as `std::variant<...>`. 119Significant backwards compatibility with v1 Outcome code was retained, as the review 120had felt the basic proposed design fine. 121 122A period of maturation then followed by porting a large existing codebase using Outcome v1 123to v2, and writing a significant amount of new code using v2 to test it for unanticipated 124surprises and bugs. Quite a few corner cases were found and fixed. At the end of September 1252017, Outcome v2 was deemed to be "mature", and a script generated "Boost edition" made 126available. 127 128All that remained before it was ready for a second Boost peer review was the 129documentation. This took four months to write (same time as to write the library itself!), 130and in January 2018 Outcome had its second Boost peer review, which it passed! 131 132## Outcome v2.1 133 134The changes requsted during the review of v2.0 were fairly modest: `result` and `outcome` would 135be renamed to `basic_result` and `basic_outcome`, and a clean separation of concerns between the 136`basic_*` layer and the "convenience" layer would be created. That suited Outcome nicely, 137as the `basic_*` layer could have minimum possible header dependencies and thus minimum possible build times 138impact, which was great for big iron users with multi-million line C++ codebases. This also 139had the nice side effect of permitting both Boost and `std` implementations to be supported 140concurrently in both Outcome and Boost.Outcome. 141 142By April 2018, v2.1 was feature complete and entered a six month period of maturation and 143battle hardening under its already extensive userbase. However Outcome passing its review in January 2018 had much more consequence than I could have ever 144expected. Unbeknownst to me, some of the WG21 leadership had interpreted the success of 145Outcome, and especially its divergences from WG21 Expected into a more complete substitute 146for C++ exception handling, as a sign that the C++ 147exception handling mechanism was no longer fit for purpose. [It was thus proposed 148to remedy the standard exception handling mechanism into something much more 149efficient, thus rendering Outcome obsolete in future C++ standards (P0709 *Zero overhead exceptions* aka "Herbceptions")](http://wg21.link/P0709). 150 151Concurrently to that, just before the review of Outcome 2.0, I had mooted a number of semantic and compile time performance 152improvements to `<system_error>` with the proposal that we mildly break Boost.System with 153improvements and see how badly real world code broke in response. This was not widely 154accepted at that time (though they have been since incorporated into Boost.System, and proposed 155defect remedies for `<system_error>` for C++ 23). I therefore wrote [an improved `<system_error2>`](https://ned14.github.io/status-code/) which fixed all the problems 156listed at [P0824 (Summary of SG14 discussion on `<system_error>`)](https://wg21.link/P0824) 157and fixed up Outcome so one could use it without any system error implementation, 158or with the STL one or with the proposed improved one. 159 160This proposed improved `<system_error2>` was proposed by me as the library support for 161P0709 *Zero overhead exceptions* in [P1095 *Zero overhead deterministic failure*](https://wg21.link/P1095), 162specifically as the implementation of P0709's proposed `std::error` value type. As 163proposed improved `<system_error2>` is bundled with Outcome in 164[experimental]({{< relref "/experimental" >}}), that means that Outcome and Boost 165users can gain the non-language benefits of one possible implementation of P0709 166today in any conforming C++ 14 compiler. 167 168At the time of writing, just before Outcome enters Boost (January 2019), Herbceptions have 169been voted upon only by SG14 Low Latency and LEWG, both giving unanimous acclamation. They have yet to be voted upon by the 170rest of the committee. The P1095 proposed implementation of P0709 has been voted upon by 171WG14 *C Programming Language*, where the C-relevant parts were approved in principle by a large majority. So 172the future currently looks hopeful that C, and C++, will gain language support for 173specifying deterministic failure sometime in the 2020s. 174 175In the meantime, Outcome is a peer reviewed, battle tested, library-only implementation 176of *Zero overhead exceptions* with proposed `std::error` available under Experimental. 177Please strongly consider helping us test the proposed `<system_error2>` based `std::error` 178design! The committee would greatly welcome empirical experience. 179