C++20 Coroutines: A Case Study in Institutional Dynamics
Great Founder Theory in C++
Abstract
This paper examines the standardization of C++20 coroutines through the lens of Great Founder Theory (GFT), Samo Burja’s framework for analyzing institutional dynamics. The coroutines saga raises questions about how implementation momentum, corporate resources, and procedural constraints shape WG21 outcomes.
1. Origins and Early Development (2012-2015)
Gor Nishanov, a Microsoft engineer, introduced “resumable functions” in 2012, with Microsoft announcing an early preview implementation in Visual Studio’s November 2013 CTP release. Nishanov’s dual role as both language designer and compiler implementer gave Microsoft significant first-mover advantage—by the time competing proposals emerged, MSVC had already shipped experimental coroutine support to millions of developers.
In April 2014, Nishanov collaborated with Gabriel Dos Reis (also Microsoft) on early design whiteboarding. Later, on a “rainy evening of 2014,” Nishanov, Richard Smith (Google/Clang), and Chandler Carruth (Google) sketched out the heap allocation elision optimization that would become central to later debates. The C++14 committee established a Coroutines Technical Specification, designating the Microsoft design as the primary standardization track.
This timeline raises a question: does early implementation create momentum that committee process struggles to redirect?
2. Technical Concerns Emerge (2018)
By 2018, Google had deployed coroutines internally and identified concerns with the design. Geoff Romer, James Dennett, and Chandler Carruth authored P0973R0 (”Coroutines TS Use Cases and Design Issues”) in March 2018, presenting a systematic analysis. The paper identified several concerns:
Implicit heap allocation and tension with C++’s zero-overhead principle
Dangerous lifetime semantics with const reference parameters
An “awkward and obscure extension point” for allocation control
Google’s engineers argued that the design emphasized Microsoft’s asynchronous use case at the expense of their primary need—error propagation with expected<T,E> in codebases where exceptions were forbidden.
Nishanov’s rebuttal (P0978R0) was emphatic: “we categorically, absolutely, emphatically, vociferously object to notion that coroutines violate zero-overhead principle.” The Microsoft response pointed to the 2014 conversation with Google engineers as evidence that heap elision was always considered feasible. This exchange revealed a dynamic: Microsoft had controlled the implementation runway for five years, making any alternative design a theoretical exercise against shipping code.
In May 2018, Google escalated with P1063R0 (”Core Coroutines”), proposing a ground-up redesign that would “expose a minimal set of coroutine primitives that map directly to the underlying implementation.” The Core Coroutines proposal acknowledged it could not be backwards-compatible with the Coroutines TS and “must be adopted before coroutines reach an IS (if at all).” Titus Winters of Google’s Abseil team publicly expressed concern: “Is anyone else uncomfortable with designs like these? Are we sure we want to rush to include coroutines in the next C++ release, even with these design smells?”
3. The Procedural Challenge (2018)
The June 2018 Rapperswil meeting saw the Evolution Working Group narrowly approve merging the Coroutines TS, only for the full plenary to narrowly reject it. The November 2018 San Diego meeting replayed this exact scenario—EWG approval, plenary rejection—with one trip report noting “the level of consensus in plenary appears to have decreased slightly since Rapperswil.” This pattern illustrated a WG21 dynamic: working groups (Mid power in GFT terms) could not overcome plenary resistance (High power), leaving the feature in limbo.
During San Diego, Lewis Baker of Facebook emerged as a bridge figure. Baker had authored the widely-used cppcoro library and contributed to Facebook’s folly::coro implementation—giving him practical credibility that purely theoretical critiques lacked. Facebook’s involvement represented a third perspective attempting to find common ground between Microsoft and Google. Baker co-authored P1241R0 (”In support of merging coroutines into C++20”) with Lee Howes (also Facebook) and Eric Niebler, arguing for incremental adoption with future improvements.
4. The Kona Resolution (February 2019)
The February 2019 Kona meeting marked the final deadline for C++20 feature decisions. Between meetings, Baker and collaborators produced P1342R0 (”Unifying Coroutines TS and Core Coroutines”), proposing an incremental path that would merge the TS while leaving room for Core Coroutines-style improvements in future standards. This paper explicitly framed the choice: “Delay the merge of Coroutines TS into the IS and wait until the exploration of the alternative design is completed (estimated completion of the exploration moves Coroutines out of C++20)” versus “Incremental: Merge the Coroutines TS and deliver solutions to the concerns mentioned as the solutions become ready for adoption.”
At Kona, the Coroutines TS achieved “very strong consensus” for merger—multiple trip reports describe the plenary vote as approximately 10:1 in favor. What changed? Several factors aligned: the “deferred layout” concept provided theoretical cover for future stack allocation optimizations; Baker’s unification paper offered an incremental improvement path; and the C++20 deadline created forcing-function pressure. As one attendee noted, “their design has not changed significantly over the past year, but there was no consensus to merge them in San Diego or Rapperswil”—the technical arguments hadn’t shifted, but something else had.
5. Library Support Gap
C++20 shipped coroutines as a raw language mechanism without any standard library support—no task, no generator, no practical abstractions. As Corentin Jabot wrote in his Kona trip report: “C++20 will not ship with any standard library support for coroutines. I am afraid this will give people a bad impression of an otherwise amazing feature.” Users were directed to third-party libraries like cppcoro or folly::coro—both authored by Lewis Baker, creating a dependency on the very person who had tried to bridge the divide.
The std::generator type, arguably the most basic coroutine abstraction, did not arrive until C++23 (P2168/P2502, authored by Baker and Corentin Jabot), and Microsoft’s implementation only shipped in Visual Studio 2022 version 17.13 in early 2025—nearly five years after coroutines entered the standard. Meanwhile, cppcoro itself remains largely unmaintained, with Baker having moved on to other work at Facebook. The institutional knowledge required to write correct coroutine types remains scattered across blog posts, conference talks, and Raymond Chen’s 61-part (and counting) tutorial series.
6. GFT Analysis
The coroutines history illustrates several institutional dynamics worth examining:
Implementation momentum: Microsoft’s five-year implementation head start created owned power (shipping code) that committee process (borrowed power) struggled to redirect. How should WG21 evaluate proposals where one implementation has years of head start?
Knowledge concentration: Nishanov served as the living knowledge repository for coroutine design. When he cited the 2014 optimization discussion, he was referencing context unavailable to many evaluators—”intellectual dark matter” in GFT terms.
Procedural iteration: The feature required three consecutive meeting cycles (Rapperswil, San Diego, Kona) to navigate EWG-to-plenary approval, with each meeting repeating similar technical debates. Did this process produce design improvement, or primarily delay?
Incomplete delivery: The committee shipped core language machinery without usable library abstractions, creating a feature that most developers cannot practically use without third-party dependencies.
Borrowed versus owned power: The Bulgarian National Body’s formal objection (nbballot issue #49) cited “serious flaws” including design problems identified in P1662R0 and P1745R0 “related to cancellation and cleanup,” noting that “eliminating these issues will require breaking changes to the current design.” The objection was overridden by plenary vote—formal process (borrowed power) could not overcome implementation momentum (owned power).
7. Questions for Reflection
The coroutines history raises questions about WG21’s process:
When one vendor has years of implementation investment, how can the committee meaningfully evaluate alternatives?
What mechanisms exist to ensure library support ships alongside language features?
When formal National Body objections cite specific technical papers, how should they be weighed?
Does the current process optimize for technical design quality, or for standardizing mature implementations?
These questions deserve attention from those who care about WG21’s effectiveness.
References
P0973R0: Romer, Dennett, Carruth. Coroutines TS Use Cases and Design Issues (2018)
P0978R0: Nishanov. Response to P0973R0 (2018)
P1063R0: Romer, Dennett, Carruth. Core Coroutines (2018)
P1241R0: Baker, Howes, Niebler. In support of merging coroutines into C++20 (2018)
P1342R0: Baker et al. Unifying Coroutines TS and Core Coroutines (2019)
P1662R0, P1745R0: Concerns regarding cancellation and cleanup
P2168, P2502: Baker, Jabot. std::generator (2020-2022)
Burja, S. (2020). Great Founder Theory.
Revisions
2025-12-23: Adjusted tone to raise questions rather than assign blame; preserved all historical facts and quotes.
We welcome corrections and additional perspectives from committee participants.


C++'s coroutine has a funny limit that `co_await` is not allowed in `catch` clauses. What if some async operation failed and then (in the `catch` clause) I need to also asynchronously load some content from disk/Internet as fallback_value/error_message? The impact is that the programmers have to use expected<T,E> as functions' return type everywhere, change `try-catch` clauses to `if` clauses and check whether `co_await` expressions result in values or errors. I.e. back to C-style error handling.