CppCast - Coroutines
Episode Date: July 19, 2017Rob and Jason are joined by Gor Nishanov to talk about the C++ Coroutines proposal. Gor Nishanov is a Principal Software Design Engineer on the Microsoft C++ team. He works on design and stand...ardization of C++ Coroutines, and on asynchronous programming models. Prior to joining C++ team, Gor was working on distributed systems in Windows Clustering team. News Verdigris: Qt without moc Trip report: Summer ISO C++ standards meeting A C++ review community Future Ruminations Gor Nishanov @gornishanov Gor Nishanov's GitHub Links CppCon 2015: Gor Nishanov "C++ Coroutines - a negative overhead abstraction" CppCon 2016: Gor Nishanov "C++ Coroutines: Under the covers" Wandbox: Coroutines with Ranges Compiler Explorer: Coroutines clang demo Sponsors Backtrace Hosts @robwirving @lefticus
 Transcript
 Discussion  (0)
    
                                         This episode of CppCast is sponsored by Backtrace, the turnkey debugging platform that helps you spend less time debugging and more time building.
                                         
                                         Get to the root cause quickly with detailed information at your fingertips.
                                         
                                         Start your free trial at backtrace.io slash cppcast.
                                         
                                         CppCast is also sponsored by CppCon, the annual week-long face-to-face gathering for the entire C++ community.
                                         
                                         Get your ticket today.
                                         
                                         Episode 110 of CppCast with guest Gore Nishina recorded July 19th, 2017. In this episode, we talk about some of the news
                                         
                                         out of the Toronto ISO C++ meeting.
                                         
                                         And we talk to Gore Nishina,
                                         
    
                                         Principal Engineer at Microsoft.
                                         
                                         Gore tells us about the C++
                                         
                                         Coroutines proposal. to C++ Coaching's Potokal.
                                         
                                         Welcome to episode 110 of CppCast, the only podcast for C++ developers by C++ developers.
                                         
                                         I'm your host, Rob Irving, joined by my co-host, Jason Turner.
                                         
                                         Jason, how are you doing today?
                                         
                                         I'm doing pretty good, Rob. How are you doing?
                                         
                                         Doing good. How'd your training go?
                                         
    
                                         I think it went well. I got some great feedback, and maybe I'll see which one I'm going to plan to do next in the future here.
                                         
                                         Okay, sounds good.
                                         
                                         Well, at the top of every episode I'd like to read a piece of feedback and
                                         
                                         we got a lot of feedback last week.
                                         
                                         So, Jason,
                                         
                                         normally we get pretty good
                                         
                                         feedback on Twitter and Facebook and
                                         
                                         everything and we did get
                                         
    
                                         at least one listener saying, you know, he always
                                         
                                         listens to CppCast on his way to brunch
                                         
                                         and he said
                                         
                                         he enjoyed this week's topic about
                                         
                                         cute without what makes cute
                                         
                                         bad for C++ devs and said it was
                                         
                                         enlightening as hell
                                         
                                         but we got some other mixed feedback as well
                                         
    
                                         and I think we kind of stumbled on
                                         
                                         a little religious war
                                         
                                         with cute devs
                                         
                                         there were a couple who
                                         
                                         I guess,
                                         
                                         were upset that we didn't press the Copper Spice developers
                                         
                                         on some of the changes they were making.
                                         
                                         And a couple different listeners pointed us to this article
                                         
    
                                         that does a comparison between Qt, Copper Spice,
                                         
                                         and this other library that you can use with Qt, which is called
                                         
                                         Vertigris. Okay. Yeah, so I'll put a link to that in the show notes. And if you are interested in
                                         
                                         reading about another library that works with Qt, it looks like this one changes the way...
                                         
                                         It gets rid of mock, but it still
                                         
                                         creates the meta object generation
                                         
                                         at compile time.
                                         
                                         So it handles the mock problem a little bit differently
                                         
    
                                         than Copper's Pice, is my understanding.
                                         
                                         So if you're interested
                                         
                                         in that, we'll put this link in the show
                                         
                                         notes, and maybe
                                         
                                         we'll talk more about that topic in the future.
                                         
                                         Yeah.
                                         
                                         Well, we'd love to hear your thoughts about the show as well.
                                         
                                         You can always reach out to us on Facebook, Twitter, or email us at feedback at cpcast.com.
                                         
    
                                         And don't forget to leave us a review on iTunes.
                                         
                                         Joining us today is Gor Nishinov.
                                         
                                         Gor is a principal software design engineer on the Microsoft C++ team.
                                         
                                         He works on design and standardization of C++ coroutines and on asynchronous programming models.
                                         
                                         Prior to joining the C++ team, Gore is working on distributed systems in the Windows clustering team.
                                         
                                         Gore, welcome to the show.
                                         
                                         Hey guys, great to be with you.
                                         
                                         So, you know, I guess, how did you end up on the compiler team?
                                         
    
                                         Well, if I track down what I've been doing, I was always jumping between the languages things and doing
                                         
                                         some production at some point, getting frustrated with the tools that I'm using
                                         
                                         and going back. So I think initially in Russia, I was on the cross
                                         
                                         compiler team that were doing software
                                         
                                         compilers partially for space industry.
                                         
                                         Then after the Soviet Union fell apart,
                                         
                                         I started doing random software,
                                         
                                         like, for example,
                                         
    
                                         Ink It Forward WordPerfect.
                                         
                                         You know, back in the 90s,
                                         
                                         we had pen computers,
                                         
                                         and Microsoft had Pen API.
                                         
                                         So you can take a WordPerfect document
                                         
                                         and then scribble on top of it with your
                                         
                                         pen, and then you can
                                         
                                         send this augmented document.
                                         
    
                                         Then I went back to
                                         
                                         school, RPI,
                                         
                                         at Rensselaer Polytechnic Institute
                                         
                                         where Alex Stepanov and
                                         
                                         Maser collaborated on the STL.
                                         
                                         It was all infused with
                                         
                                         C++, so in
                                         
                                         1996 I thought I learned how to use C++ properly.
                                         
    
                                         So I went back into the product team.
                                         
                                         So it was a Windows NT team.
                                         
                                         And after applying C++ extensively for 15 years, I got frustrated.
                                         
                                         So I decided to go back.
                                         
                                         I mean, future, stoop future is what triggered me.
                                         
                                         That, like, it's so wrong.
                                         
                                         I have to go and start working on that.
                                         
                                         Oh, well, you know, now I need to know
                                         
    
                                         if we should wait until the actual interview portion
                                         
                                         so you can tell us all the ways that std future is wrong,
                                         
                                         or if you want to tell us now mild and calm. But that's what prompted me, at least.
                                         
                                         Yeah, the asynchronous programming and tools that are not sufficient enough in C++ that I decided to go and try to help.
                                         
                                         Well, I will bring up StudeFuture in a little bit, but I've got to ask, while we're still talking about your bio,
                                         
                                         what was it like working in the space industry and compilers involved and that kind of thing?
                                         
                                         I was young, I didn't know. I simply was a writing compiler
                                         
                                         front-end, was modular, and also worked on the register allocator in our
                                         
    
                                         middle, or close to the
                                         
                                         back-end. But then there were people who actually middle or close to the back end.
                                         
                                         But then there were people who actually communicated
                                         
                                         and were sending the data.
                                         
                                         I never interacted directly with the space industry.
                                         
                                         Okay.
                                         
                                         So what year was that that you were working on that,
                                         
                                         if you don't mind?
                                         
    
                                         Early 90s, maybe end of 89, 90, 91.
                                         
                                         Okay.
                                         
                                         I was just thinking about automatic register allocation
                                         
                                         and how the register keyword
                                         
                                         has never really been terribly useful in my opinion.
                                         
                                         Well.
                                         
                                         Was it useful back then in the late 80s, early 90s?
                                         
                                         Or were you still just doing what you wanted to do?
                                         
    
                                         I was doing a modular
                                         
                                         front-end.
                                         
                                         Okay.
                                         
                                         So modular, modular, modular.
                                         
                                         It did not have
                                         
                                         any register keyword.
                                         
                                         It's the register allocator
                                         
                                         that is doing lowering
                                         
    
                                         after
                                         
                                         you're done with the syntactic sugar.
                                         
                                         Right. Okay, well, Gore, we've got a couple news articles to talk about. after you're done with the syntactic sugar.
                                         
                                         Right.
                                         
                                         Okay, well, Gore, we've got a couple news articles to talk about.
                                         
                                         We'd love to get your thoughts on these,
                                         
                                         and then we'll dig more into coroutines, okay?
                                         
                                         Sure.
                                         
    
                                         Okay.
                                         
                                         So this first one is Herb Sutter's trip report from the Toronto ISO C++ meeting
                                         
                                         that just finished up a couple days ago.
                                         
                                         And it sounds like this was a pretty eventful meeting.
                                         
                                         The big headline that came out of it is that the concepts TS has been merged
                                         
                                         into the draft of C++ 20.
                                         
                                         Gore, did you make it to this one?
                                         
                                         Oh, yes, yes.
                                         
    
                                         It was a very exciting meeting.
                                         
                                         So concept, for example, for a while there was a big
                                         
                                         struggle to get them in but people
                                         
                                         were disagreeing about some of the
                                         
                                         natural
                                         
                                         syntax for them and they wanted
                                         
                                         to have more to type
                                         
                                         and eventually
                                         
    
                                         deciding to
                                         
                                         separate
                                         
                                         the natural
                                         
                                         syntax from the rest of the proposal.
                                         
                                         Yeah, and as of now...
                                         
                                         It started moving forward,
                                         
                                         and Andrew Sutton and Richard Smith and Core
                                         
                                         was frantically carving out the proposal,
                                         
    
                                         because I think it's relatively unusual
                                         
                                         that such huge change was done on the working paper during the week.
                                         
                                         So they carved, then they healed the wounds, they re-reviewed the code,
                                         
                                         and it was approved for merging into C++20, or at least the working paper that targets C++20. Then, you know from the article and from
                                         
                                         the other reports is that
                                         
                                         we got four TSS
                                         
                                         out. We got three
                                         
                                         techno-specifications,
                                         
    
                                         network and coroutines,
                                         
                                         and ranges, and
                                         
                                         finally modules moved
                                         
                                         into the PDTS stage,
                                         
                                         which is preliminary draft
                                         
                                         techno-specifications. So a lot of stuff was moved during this moved into the PDTS stage, which is Preliminary Draft Techno Specification.
                                         
                                         So a lot of stuff was moved during this meeting.
                                         
                                         It was fantastic.
                                         
    
                                         So for our listeners who are familiar with concepts,
                                         
                                         if I understand correctly, in the proposal there was three different ways
                                         
                                         with which a concept could be introduced,
                                         
                                         and now we've removed some of them or something?
                                         
                                         Yeah, we removed two.
                                         
                                         So essentially, there is a full syntax,
                                         
                                         which looks like a template syntax,
                                         
                                         but additionally, you can say requires,
                                         
    
                                         and you put concept names in places
                                         
                                         where you had type name or a class, right,
                                         
                                         in the template introducer.
                                         
                                         But additionally, there was
                                         
                                         a natural syntax or function-like
                                         
                                         syntax where you can simply write a function
                                         
                                         and instead of saying
                                         
                                         int, you can say a number
                                         
    
                                         or something like
                                         
                                         that, and it will
                                         
                                         be essentially a template function with
                                         
                                         restricted template parameter
                                         
                                         to just the number concept. So that was removed.
                                         
                                         And then there is another version of introducers where you have some
                                         
                                         relationship between the concepts which was
                                         
                                         slightly more complicated but still less
                                         
    
                                         cumbersome than the full template syntax. It was also removed.
                                         
                                         So we right now have only one,
                                         
                                         the biggest one, and then
                                         
                                         people agreed that they really want the
                                         
                                         short syntax as well. It'll just
                                         
                                         take a little bit longer to get there.
                                         
                                         Okay, so you think the short syntax
                                         
                                         will make it in after it stays in the TS
                                         
    
                                         a bit longer and maybe has some of the language
                                         
                                         changed a bit? Oh, I really hope
                                         
                                         so. I think people initially
                                         
                                         want to have big in-your-face
                                         
                                         syntax, but after using it for a while, they get tired of it. They're like, okay, I know it's a
                                         
                                         concept. Okay, okay, let me just write it simply. So I think that that will happen. Just from the
                                         
                                         usage, people would start using with the heavyweight syntax, and they would want a lighter syntax at some point.
                                         
                                         Was there anything else, maybe not related to coroutines,
                                         
    
                                         that you wanted to call out from Toronto that was big news?
                                         
                                         Oh, yes. There were a few little things.
                                         
                                         One of them I liked was designated initializers.
                                         
                                         Have you seen those?
                                         
                                         Yeah, I did see that.
                                         
                                         Yes.
                                         
                                         I was curious about the syntax.
                                         
                                         How do you do the dot member name
                                         
    
                                         instead of just member name equals whatever value?
                                         
                                         Well, it came from C.
                                         
                                         So there were three design goals
                                         
                                         for Genesic-leaded initializers.
                                         
                                         And one of them improved compatibility with C
                                         
                                         because if you look at Linux kernel, it's all
                                         
                                         over the place. So everybody's using this
                                         
                                         dot field name notation.
                                         
    
                                         So because
                                         
                                         of that goal, we went
                                         
                                         with exactly the same syntax as
                                         
                                         C.
                                         
                                         But it is so much better
                                         
                                         than C.
                                         
                                         Really.
                                         
                                         Let's see what you guys think.
                                         
    
                                         So in C, these designators, they're optional.
                                         
                                         So you can use on half of your members.
                                         
                                         You can say a name,.a,.x.
                                         
                                         And then others, you just put numbers or whatever values are. In Z++, you either use
                                         
                                         normal initialization
                                         
                                         or you use designated initializers.
                                         
                                         You cannot do half and half.
                                         
                                         So if you
                                         
    
                                         choose to say.x
                                         
                                         equals 5, you cannot just say
                                         
                                         3, 4,
                                         
                                         4y. If you go
                                         
                                         that way, you go all the way.
                                         
                                         Another cool difference from C is that
                                         
                                         in C you can do them in random order. That's one. And second,
                                         
                                         evaluation order of the expressions that you put there
                                         
    
                                         is unspecified.
                                         
                                         Well, in C++ we're saying
                                         
                                         they must be in the order of declarations.
                                         
                                         And the order is left to right.
                                         
                                         I think it's wonderful.
                                         
                                         Okay, okay.
                                         
                                         So we're thinking about the fact that objects are going to be initialized in the order that they're declared inside the struct,
                                         
                                         regardless of how we did the initialization, designated initializers, right? But you're enforcing it by saying the designated initializers
                                         
    
                                         must be in the same order they're declared, correct?
                                         
                                         So, okay, then why don't we go and fix class initializer lists
                                         
                                         so that they are required to be in the order that they're declared also?
                                         
                                         Well, one step at a time, but I think we put a foot in the door with this one.
                                         
                                         So essentially, these initializers,
                                         
                                         I really love them in a way how they cleaned up
                                         
                                         the same facility which came from C.
                                         
                                         And there are other little tweaks
                                         
    
                                         like the one I described, which are very nice.
                                         
                                         Okay.
                                         
                                         That's interesting. I'm going to have to play with that.
                                         
                                         Do you know if any compilers currently support that syntax?
                                         
                                         Clang.
                                         
                                         Clang does? Okay.
                                         
                                         I assumed it had been tested in some compilers already.
                                         
                                         Well, yeah, the proposal came with Richard Smith and Chandler
                                         
    
                                         in the list of authors,
                                         
                                         so I assume that they actually implemented before proposing
                                         
                                         right okay
                                         
                                         okay this next thing we have to talk about
                                         
                                         is another proposal
                                         
                                         coming out of meeting C++
                                         
                                         and this is for a C++ review
                                         
                                         community and I thought this was
                                         
    
                                         a pretty interesting idea
                                         
                                         basically if you
                                         
                                         want to you know if you make a library and you want to get some feedback on it, there's a new
                                         
                                         subreddit set up, which is cpp underscore review. And you can make a post about your library there.
                                         
                                         And this isn't starting until August. We'll have to see how it actually works. But
                                         
                                         you'll be able to go on and look at this person's library, submit feedback, and hopefully the library authors get some good feedback.
                                         
                                         And at the end of the process,
                                         
                                         you'll maybe get a meeting C++ review badge for your library
                                         
    
                                         to show that you were successfully reviewed.
                                         
                                         I thought that was a neat idea.
                                         
                                         Yeah, I agree it's a neat idea
                                         
                                         because the boost process is big and difficult.
                                         
                                         Not everyone wants to be a part of Boost.
                                         
                                         So just having some way to say that, yes, this library meets some minimum set of standards or something, it's a good idea.
                                         
                                         Yeah, and not every library should be a part of Boost.
                                         
                                         You might just have a very small library that just doesn't fit in there.
                                         
    
                                         Or a very big library that you don't want to
                                         
                                         try to go through the effort.
                                         
                                         Right.
                                         
                                         Well, I'm wondering how people
                                         
                                         will be able to donate
                                         
                                         time to do those
                                         
                                         things. For example,
                                         
                                         in open source community like Clan,
                                         
    
                                         you do it by barter, right?
                                         
                                         You review somebody else's
                                         
                                         patches they review yours or maybe you bribe them with gifts and other offerings or something like
                                         
                                         that uh but uh since uh since this certification process is not geared to any particular project
                                         
                                         uh i am just curious how it will work out i I mean, it's a great idea. I just,
                                         
                                         I want to see how it goes. Sure. Right. Yeah. Hopefully some people are interested in,
                                         
                                         you know, giving their time to it. Okay. And then we were talking about futures earlier.
                                         
                                         Sean Parent wrote this article on, titled Future Ruminations. And he's kind of going into a deep dive about his thoughts
                                         
    
                                         about futures and the future of futures.
                                         
                                         And since we talked with you, Gore,
                                         
                                         about how that's how you got involved in asynchronous programming,
                                         
                                         I was wondering if you had any thoughts on this.
                                         
                                         Oh, it's a wonderful article.
                                         
                                         There are a lot of good things there
                                         
                                         about cleaning up the interface
                                         
                                         to the future,
                                         
    
                                         treating it as the handle to work
                                         
                                         and consolation, which is very important.
                                         
                                         But I'm not sure
                                         
                                         whether futures
                                         
                                         will be something that we will
                                         
                                         be actually using in the future.
                                         
                                         So I do not see the future for the future.
                                         
                                         But I'm trying to avoid puns, but they just happen.
                                         
    
                                         With the future, it's very easy.
                                         
                                         But essentially, you can have several ways of writing your asynchronous code.
                                         
                                         One is using callbacks, right? And that is not very convenient, at least for some people. They hate writing state machines.
                                         
                                         Others probably would use coroutines, which are the same state machine simply written in an imperative fashion. So if you use coroutines, you don't
                                         
                                         need full functional futures. You just need some kind of ability to explain what happens
                                         
                                         after you resume the coroutine, and we can talk about it later. So composition of your
                                         
                                         code using future with dot, and other operations,
                                         
                                         I'm not sure there will be use cases for that.
                                         
    
                                         That's some pretty strong words.
                                         
                                         Well, yes, because there is a much more powerful construct like a reactive string.
                                         
                                         I'm not sure whether you have seen RxCPP or reactive extensions in Java, JavaScript.
                                         
                                         But essentially, those are streams of values
                                         
                                         that appear in time.
                                         
                                         So imagine the timeline, right, going to the right.
                                         
                                         And then you have zero or more values
                                         
                                         appearing at some point in time.
                                         
    
                                         And then in the end, your sequence either never terminates,
                                         
                                         so values keep coming, or it terminates with an error,
                                         
                                         or it terminates because there is no more things.
                                         
                                         So for those reactive streams, there is algebra.
                                         
                                         There are hundreds of operations,
                                         
                                         and you have extremely expressive declarative
                                         
                                         programming model where you're describing what you want to do and you can see you
                                         
                                         know programs which is very difficult to write normally takes five six lines to
                                         
    
                                         write with those reactive strings so I think that this will be the two extremes
                                         
                                         for people who want to write declaratively, reactive streams would be something that people would compose in a similar way how ranges TS works.
                                         
                                         With ranges, you have those little combiners and you compose multiple actions that transform your streams or iterables.
                                         
                                         And in the end, you get something else.
                                         
                                         But it's a nice, it's a high-level description.
                                         
                                         So you don't deal with implementation details.
                                         
                                         You just say how you compose those operations.
                                         
                                         And similarly, with reactive asynchronous streams,
                                         
    
                                         there are actions you can do, and there are a lot of them.
                                         
                                         So I think in the future, we will see those two extremes.
                                         
                                         If you want simply to write
                                         
                                         as in code and express your code procedurally
                                         
                                         as the
                                         
                                         procedural function
                                         
                                         do that, do that.
                                         
                                         If something else, do this or else
                                         
    
                                         and then sometimes wait
                                         
                                         on a bunch of activities and then do that
                                         
                                         so that will be expressed like a normal function
                                         
                                         but with co-await
                                         
                                         as the coroutine.
                                         
                                         And on the other end,
                                         
                                         we will have declarative programming with reactive stream.
                                         
                                         Future just not expressive enough.
                                         
    
                                         It is a workaround for the absence of coroutines.
                                         
                                         So I do not think that futures will be something that we will be using.
                                         
                                         So the reactive streams, are they dependent on coroutines
                                         
                                         also, or is this a completely separate proposal?
                                         
                                         It's a completely separate proposal, and they can
                                         
                                         interact with coroutines, but they're independent.
                                         
                                         So usually a coroutine would be on the consuming side.
                                         
                                         For example, in coroutines we have for a wait statement, which allows you to iterate on a synchronous stream.
                                         
    
                                         So that was put there with the noise that reactive streams will come.
                                         
                                         So the coroutine could be on the consumption side of the reactive
                                         
                                         stream or on production side
                                         
                                         of the reactive stream.
                                         
                                         Or you can even have an element where you
                                         
                                         co-await something and then yield.
                                         
                                         So you
                                         
                                         will talk about that maybe
                                         
    
                                         in the coroutine part of the discussion.
                                         
                                         But you can
                                         
                                         mix a weight and yield in
                                         
                                         the same coroutine. And the result is a synchronous stream
                                         
                                         because we can suspend and then yield values,
                                         
                                         but in a synchronous fashion.
                                         
                                         We do not do it in a block in a synchronous fashion.
                                         
                                         So coroutines will interact with those asynchronous streams,
                                         
    
                                         but those two programming models, procedural and declaratives,
                                         
                                         they are both very useful
                                         
                                         because they can express different things
                                         
                                         in a nice, concise fashion.
                                         
                                         And those are the two things that will, I think, remain.
                                         
                                         I'm not sure what is the future for the future.
                                         
                                         Again, no pun intended.
                                         
                                         It's just that, how else would you say it?
                                         
    
                                         Right.
                                         
                                         Okay, so since we're talking about
                                         
                                         await and yield and everything,
                                         
                                         for listeners who haven't heard
                                         
                                         or aren't too familiar with the coroutines proposal,
                                         
                                         could you give us an overview?
                                         
                                         Sure.
                                         
                                         So at the high level,
                                         
    
                                         coroutines are functions
                                         
                                         which get two more operations.
                                         
                                         So normal functions,
                                         
                                         they have two operations,
                                         
                                         call and return.
                                         
                                         That's all you can do. There is a call syntax, you know,
                                         
                                         f, parens, and the new pass some parameters, and then inside of the function body, you have a return statement that
                                         
                                         you can provide a value to return back to whomever called you.
                                         
    
                                         So coroutines get two more. They have a point
                                         
                                         where a function execution can be suspended
                                         
                                         and control returns back to its caller.
                                         
                                         And then there is a way to resume the coroutine.
                                         
                                         And how you resume it depends on the semantic of the coroutine.
                                         
                                         So in C++, unlike in other languages,
                                         
                                         we decided to make coroutines open-ended.
                                         
                                         The language does not define
                                         
    
                                         the semantic. I mean, eventually
                                         
                                         in the library we will get coroutine
                                         
                                         types that have some
                                         
                                         defined semantic, but
                                         
                                         as it stands today, coroutines
                                         
                                         are just a language facility
                                         
                                         which allows you to annotate
                                         
                                         where in the function
                                         
    
                                         you can suspend
                                         
                                         and give
                                         
                                         an ability, a glue,
                                         
                                         to add in library abstractions
                                         
                                         that will explain what happens
                                         
                                         when coroutine is suspended and resumed.
                                         
                                         For example, the simplest one would be a generator.
                                         
                                         It's a coroutine which produces
                                         
    
                                         potentially infinite lazy
                                         
                                         sequence. So from the outside
                                         
                                         it looks like an iterable.
                                         
                                         So you say generator of
                                         
                                         int, f, and then whatever is
                                         
                                         inside. So
                                         
                                         you will use it the same way
                                         
                                         like you use any
                                         
    
                                         iterable that has begin and end.
                                         
                                         You can go to your range-based
                                         
                                         for, you can give
                                         
                                         it to any standard algorithm, which takes
                                         
                                         begin and end. With
                                         
                                         ranges, it's even easier. You just pass
                                         
                                         this coroutine, which is an input range,
                                         
                                         to any algorithm which expects
                                         
    
                                         range. And then, whenever
                                         
                                         your algorithm does plus-plus
                                         
                                         on an iterator, it
                                         
                                         jumps back into the coroutine
                                         
                                         and continues from the point where it was stopped.
                                         
                                         So it is a way to write a state machine,
                                         
                                         but in a procedural fashion.
                                         
                                         So you write your code and say,
                                         
    
                                         co-yield some expression.
                                         
                                         When you reach co-yield expression,
                                         
                                         that value that is being yielded
                                         
                                         will become available to an iterator which
                                         
                                         consumes the result of the coroutine at star, at the reference iteration on the iterator.
                                         
                                         And when you do plus plus, you jump back into the coroutine right at the point after it
                                         
                                         was yielding something.
                                         
                                         And it'll continue.
                                         
    
                                         So this is...
                                         
                                         I'm sorry, I thought there was some question.
                                         
                                         No, go ahead.
                                         
                                         Okay.
                                         
                                         And this is similar to what we have in Python,
                                         
                                         I think now in JavaScript, in C Sharp, in Dart,
                                         
                                         and in many other languages.
                                         
                                         So it's not unique in that respect.
                                         
    
                                         What is unique in C++ is how efficient they are
                                         
                                         and that they are fully open.
                                         
                                         You decide what does it mean to yield.
                                         
                                         We don't have a prescribed way, prescribed generator.
                                         
                                         You can plug in your own if you dislike what we offer in the standard
                                         
                                         and right now just to give an ability to people to experiment
                                         
                                         and come up with the awesome generators
                                         
                                         that we will standardize in the future
                                         
    
                                         we don't even offer you a generator
                                         
                                         but it takes only 15 lines to write
                                         
                                         so maybe 50 if you include the iterators
                                         
                                         and a lot of comments.
                                         
                                         So this is one use case.
                                         
                                         Another would be an asynchronous task.
                                         
                                         So it's before you use callbacks
                                         
                                         or maybe future.then is that you are saying,
                                         
    
                                         I'm going to call the sync API.
                                         
                                         And when it continues,
                                         
                                         and when, for example, I'm trying to connect to a socket.
                                         
                                         And once the connection is established, you will resume the coroutine from that point.
                                         
                                         So it allows you to write code as if it was synchronous.
                                         
                                         The only exception is that at those points where your synchronous code would block,
                                         
                                         you would use co-await to signify that you want, at this point,
                                         
                                         to suspend the coroutine.
                                         
    
                                         And then, in co-await mechanics,
                                         
                                         there is a way to explain to the compiler
                                         
                                         how to resume the coroutine once the task is finished.
                                         
                                         And then, so far, we looked at two different cases.
                                         
                                         A simple asynchronous task and a generator.
                                         
                                         But you can mix and match, because it's you who defined the semantic of those.
                                         
                                         So you can say, if your function contains both yields and a weight,
                                         
                                         then the abstraction it represents would be an asynchronous stream,
                                         
    
                                         which can produce values, but it can suspend in between producing the values.
                                         
                                         Interesting.
                                         
                                         I wanted to interrupt this discussion for just a moment to bring you a word from our sponsors.
                                         
                                         Backtrace is a debugging platform that improves software quality, reliability, and support
                                         
                                         by bringing deep introspection and automation throughout the software error lifecycle.
                                         
                                         Spend less time debugging and reduce your mean time to resolution
                                         
                                         by using the first and only platform to combine symbolic debugging, error aggregation, and state analysis.
                                         
                                         At the time of error, Bactres jumps into action, capturing detailed dumps of application and environmental state.
                                         
    
                                         Bactres then performs automated analysis on process memory and executable code to classify errors and highlight important signals such as heap corruption, malware, and much more. This data is aggregated and archived in a centralized object store, providing your team
                                         
                                         a single system to investigate errors across your environments. Join industry leaders like Fastly,
                                         
                                         Message Systems, and AppNexus that use Backtrace to modernize their debugging infrastructure.
                                         
                                         It's free to try, minutes to set up, fully featured with no commitment necessary.
                                         
                                         Check them out at backtrace.io slash cppcast.
                                         
                                         Now, I want to clear up something, if that's all right.
                                         
                                         You've mentioned ranges several times,
                                         
                                         and I think that you're saying, like,
                                         
    
                                         just a normal begin-end iterator pair like we're used to currently,
                                         
                                         but how does this interact with the ranges TS proposal?
                                         
                                         I mean, the ranges TS that's presumably coming up also.
                                         
                                         It interacts wonderfully.
                                         
                                         Casey Carter written adapters, which allows to plug in coroutines into ranges.
                                         
                                         And it's even available on a wand box.
                                         
                                         So I can send you a link so you can see how Coroutine
                                         
                                         plays with ranges. Because
                                         
    
                                         I think in classification that
                                         
                                         Casey did,
                                         
                                         Coroutine is an input
                                         
                                         range,
                                         
                                         because you can only
                                         
                                         read from it. You can never go
                                         
                                         back.
                                         
                                         And essentially, whichever
                                         
    
                                         algorithm can work over the input
                                         
                                         ranges, you can
                                         
                                         give to that algorithm the coroutine
                                         
                                         itself. And then
                                         
                                         the algorithms would
                                         
                                         pull the values out of the range, and
                                         
                                         every time you pull, you jump inside
                                         
                                         of the coroutine and continue
                                         
    
                                         from the latest yield point.
                                         
                                         So we'll definitely have to
                                         
                                         share that link in the show notes
                                         
                                         if you can give us one.
                                         
                                         Yeah, sure thing.
                                         
                                         Definitely something our listeners would want to see.
                                         
                                         So what's the current status of the coroutines proposal?
                                         
                                         Was there any big news for coroutines out of Toronto?
                                         
    
                                         Well, it was published as a technical specification.
                                         
                                         We have now two implementations,
                                         
                                         one in Clang, another
                                         
                                         in MSVC. And Clang we missed 4.1 by just, I think, a week. So it will be in whatever
                                         
                                         the release comes after 4.1. But hey, if you can build your clang from trunk, go ahead.
                                         
                                         And Eric Fizili here already
                                         
                                         added the library support, so
                                         
                                         we are complete there.
                                         
    
                                         You need to grab both
                                         
                                         the clang and
                                         
                                         the library that comes with it.
                                         
                                         But if you don't want
                                         
                                         a library, that's
                                         
                                         fine too, because
                                         
                                         it's just one little file that is required for coroutines to work.
                                         
                                         So there is this little file that defines the glue which links language support with coroutine abstractions that you want to provide.
                                         
    
                                         And it's a very small file which links those two together.
                                         
                                         You can just cut and paste it. You don't have to even have an entire library.
                                         
                                         So have you been involved in both Visual Studio
                                         
                                         and the Clang implementations of coroutines?
                                         
                                         Yes.
                                         
                                         Okay.
                                         
                                         Yes.
                                         
                                         Especially in Clang and all of EM
                                         
    
                                         because there, yes, I did probably most of the work.
                                         
                                         In MSVC, I had help.
                                         
                                         Okay.
                                         
                                         I thought I had heard that in LLBM.
                                         
                                         Hold on.
                                         
                                         Richard Smith provided initial implementation of the parsing of the coroutines,
                                         
                                         but then he got busy with something else,
                                         
                                         so I plugged in the back end
                                         
    
                                         it's where the heart of the coroutine is
                                         
                                         and added whatever was missing
                                         
                                         in the front end to work
                                         
                                         with the back end implementation
                                         
                                         and the good part is that now LLVM itself has coroutines
                                         
                                         which is in the back end
                                         
                                         thus people in Rust and in Python and other languages
                                         
                                         which target LLVM IR can get the same benefit
                                         
    
                                         or as efficient coroutines within reason in their language as C++.
                                         
                                         Yeah, that's what I thought that I had heard,
                                         
                                         and you just confirmed that it's actually an LLVM IR thing.
                                         
                                         It's primitive in LLVM, I guess, is to coroutine.
                                         
                                         Yes.
                                         
                                         So there is a bunch of intrinsics,
                                         
                                         and you can describe your coroutine in pure LLVM,
                                         
                                         and then LLVM will actually turn your function into a coroutine.
                                         
    
                                         And the reasoning behind is that we wanted
                                         
                                         coroutines to be very efficient.
                                         
                                         And initially I thought
                                         
                                         I could completely implement
                                         
                                         coroutines in Clang because it has this
                                         
                                         wonderful AST and you can party
                                         
                                         on it and rewrite, change
                                         
                                         it, but
                                         
    
                                         after some experimentation, we
                                         
                                         ended up roughly
                                         
                                         with the same decomposition into backend and frontend as in MSVC,
                                         
                                         where coroutine is fully represented in LLVM IR as a function,
                                         
                                         and it travels through the optimization pipeline as a function.
                                         
                                         And the reason for that is optimizers are very good at optimizing functions.
                                         
                                         They are not very good at optimizing state machines.
                                         
                                         So essentially, we describe coroutine as a normal function.
                                         
    
                                         It is optimized like a normal function.
                                         
                                         But just before it is eligible for inlining into its colors,
                                         
                                         then we do the transformation of a coroutine into a state machine so we delayed as far as we could
                                         
                                         the transformation so that we get
                                         
                                         most inline optimization
                                         
                                         opportunities as possible
                                         
                                         Can you speak to how efficiently MSVC is also able
                                         
                                         to do this?
                                         
    
                                         I am not going to talk about that.
                                         
                                         Because, well, the reason is
                                         
                                         our initial implementation of coroutines in MSVC,
                                         
                                         the purpose was to verify the glue,
                                         
                                         to verify the model.
                                         
                                         So we focused just to make it work.
                                         
                                         So that was the prototype, and Clang got all of
                                         
                                         the benefit of knowing how the original
                                         
    
                                         implementation was done.
                                         
                                         No,
                                         
                                         it's not a prototype.
                                         
                                         It's a production
                                         
                                         version. It's just that we optimized
                                         
                                         for different things.
                                         
                                         We were trying
                                         
                                         to prove the overall design,
                                         
    
                                         but it's still usable.
                                         
                                         It's just not as efficient as we would like to yet.
                                         
                                         But in LLVM, we went into a different approach.
                                         
                                         We just said, okay, let's see,
                                         
                                         can we get it optimized the way we like?
                                         
                                         And that was the focus
                                         
                                         because the rest of the coroutine design
                                         
                                         was already verified and embedded in MSVC,
                                         
    
                                         so we focused just purely on the optimization opportunities.
                                         
                                         Okay, so we've brought up this optimization
                                         
                                         and all this several times now.
                                         
                                         So how much overhead is there in using coroutines
                                         
                                         and in adding the subtraction?
                                         
                                         Depending on the scenario, it could be zero.
                                         
                                         For example, in CppCon last year, I showed that generator optimizes into a constant.
                                         
                                         If you are iterating over generator over a fixed range.
                                         
    
                                         And even though, in general case, coroutines involve heap allocation,
                                         
                                         for common cases we eliminate those heap allocations. So the rule is very simple.
                                         
                                         As long as the lifetime of a coroutine is fully enclosed in the lifetime of its caller, we place the
                                         
                                         state of the coroutine onto the caller's frame.
                                         
                                         So thus, if you have a generator, you know, 4x over some kind of fancy generator, then
                                         
                                         you loop over it.
                                         
                                         That entire coroutine is purely on the stack.
                                         
                                         If you use structured programming, and by that I mean that you break your big function into smaller functions,
                                         
    
                                         even though you don't even call them more than once, it's the same thing.
                                         
                                         Now we're going with asynchronous tasks. So if your asynchronous task is broken into subtasks,
                                         
                                         which are broken into further subtasks,
                                         
                                         and you simply call a wait on that subtask,
                                         
                                         again, lifetime of the subtask is fully enclosed in the lifetime of a task.
                                         
                                         So it becomes simply a state,
                                         
                                         it's is local variable
                                         
                                         on the caller side
                                         
    
                                         and then all of the inlining
                                         
                                         works like normal
                                         
                                         so for a whole
                                         
                                         bunch of scenarios we are
                                         
                                         making them zero overhead
                                         
                                         okay
                                         
                                         since you have coroutines
                                         
                                         in MSVC now
                                         
    
                                         do you know if anyone's internally using coroutines in MSVC now,
                                         
                                         do you know if anyone's internally using coroutines?
                                         
                                         Yes. Has it changed how they're programming?
                                         
                                         Are programmers at Microsoft really enjoying them?
                                         
                                         Yes, yes, yes.
                                         
                                         We had several teams using them in production.
                                         
                                         We also have external developers using coroutines, for example.
                                         
                                         You know Tidal?
                                         
    
                                         There is a music service Tidal.
                                         
                                         Some kind of music streaming something.
                                         
                                         And the unofficial Tidal streaming app is written with coroutines.
                                         
                                         And you can see on GitHub and search for Coia Wait, and you will find them.
                                         
                                         And inside, we have several teams using the coroutines and also modern CPP.
                                         
                                         I think you talked with Kenny Kerr some time ago.
                                         
                                         Well, it's all based on coroutines.
                                         
                                         Not only on the use side, but also on the production side.
                                         
    
                                         So to generate the projection, he uses generators.
                                         
                                         But on the consumption side, when people write async code,
                                         
                                         well, entire WinRT is asynchronous.
                                         
                                         So without coil weight, it's extremely painful to work with it.
                                         
                                         So it does sound fair to say
                                         
                                         that this is proven and
                                         
                                         you're using it.
                                         
                                         And so are you expecting
                                         
    
                                         that we'll see it merged into
                                         
                                         C++20 like
                                         
                                         Concepts was soon?
                                         
                                         We have merged
                                         
                                         criterias and one of the
                                         
                                         part of the merged criteria, one
                                         
                                         implementation not tainted by me.
                                         
                                         So one coroutine implementation,
                                         
    
                                         which is done from the technical specification wording
                                         
                                         as opposed to, you know, from talking to Gore,
                                         
                                         what does it mean?
                                         
                                         And to a degree, EDG might count as that Edison design group.
                                         
                                         But ideally,
                                         
                                         we would love GCC to implement it too
                                         
                                         so we can compare
                                         
                                         and see who is faster.
                                         
    
                                         That, I think,
                                         
                                         is an overlooked...
                                         
                                         We have the tendency to complain
                                         
                                         about not all the compilers being up to conformance
                                         
                                         in particular categories,
                                         
                                         whatever. But I think it's one
                                         
                                         of the key strengths of C++, personally, that people complain about I think it's one of the key strengths
                                         
                                         of C++ personally
                                         
    
                                         that people complain about
                                         
                                         without realizing it's a strength
                                         
                                         that having these competing implementations
                                         
                                         verifies that the spec makes sense
                                         
                                         and verifies that we have solid compilers.
                                         
                                         Right.
                                         
                                         So I think to streamline TS process,
                                         
                                         last meeting in Kona,
                                         
    
                                         there was a discussion of having a merge criteria.
                                         
                                         And once merge criteria are met,
                                         
                                         it's nearly automatic merge process.
                                         
                                         Not sure whether it will work in this way,
                                         
                                         but maybe.
                                         
                                         So in the case of a coroutine, criterias are one independent implementation,
                                         
                                         a bunch of tests so that people can verify implementation against the tests, and adapters
                                         
                                         so that whatever is already in the working paper interacts nicely with coroutines. So
                                         
    
                                         if we have future.then in the working paper of the standard,
                                         
                                         then we'll have adapters that will work with coroutines.
                                         
                                         And we will throw in a generator just in case.
                                         
                                         Does the spec make any overhead guarantees?
                                         
                                         Or maybe to phrase it a different way,
                                         
                                         is the test suite that you're working on
                                         
                                         going to have anything that tests the overhead of the implementation?
                                         
                                         I think we will add one just for the kicks
                                         
    
                                         because it is a bragging right.
                                         
                                         We cannot demand it to be that fast or that good,
                                         
                                         but it would be fun to compare compilers.
                                         
                                         Right.
                                         
                                         It strikes me as one of the few core language features
                                         
                                         that at least because,
                                         
                                         maybe just because I have a hard time
                                         
                                         wrapping my mind around what exactly it's doing,
                                         
    
                                         that is difficult to actually demonstrate
                                         
                                         why it's a zero overhead.
                                         
                                         If that makes sense.
                                         
                                         Well, just go to Godbolt and see what's going on.
                                         
                                         Well, yes, always can do that.
                                         
                                         Yes.
                                         
                                         You've mentioned the coroutine-specific keywords a couple times,
                                         
                                         like co-wait and co-yield.
                                         
    
                                         Is the co- underscore going to be the final language?
                                         
                                         Because I know if we watch one of your videos from two years ago at CppCon, you were just saying await and yield.
                                         
                                         Yes, I fought valiantly.
                                         
                                         But I couldn't.
                                         
                                         It essentially started with yield.
                                         
                                         Yield was the problematic keyword.
                                         
                                         Okay.
                                         
                                         And some people felt that return is too confusing.
                                         
    
                                         And then for consistency, how about we'll add core everywhere?
                                         
                                         And now there is actually a benefit of having a core return
                                         
                                         because unlike other languages like C Sharp, Dart,
                                         
                                         and others that have similar await and yield keywords,
                                         
                                         they all require some kind of tag on a function.
                                         
                                         For example, in C Sharp, it's async.
                                         
                                         In Dart, it's sync star.
                                         
                                         In Rust, they're talking about fn star or something like that. So that allows them to give a different
                                         
    
                                         meaning to await or yield keyword within the coroutine because they know the
                                         
                                         context. In C++ coroutine is just a function that has correturn, co-yield or
                                         
                                         co-await. You don't have anything extra on the function signature or a function definition.
                                         
                                         And that is part of the design
                                         
                                         because we wanted to have seamless interaction
                                         
                                         with the rest of the language.
                                         
                                         We did not want to have a different corin convention
                                         
                                         or change the type system.
                                         
    
                                         So from the outside, coroutine is a normal function.
                                         
                                         It is undistinguishable from any other function.
                                         
                                         It's only the implementation.
                                         
                                         Oh yeah, yes. For example,
                                         
                                         assume that
                                         
                                         dot then in some
                                         
                                         form will appear in the future.
                                         
                                         In the future.
                                         
    
                                         And
                                         
                                         your function says
                                         
                                         std future of int
                                         
                                         f blah
                                         
                                         semicolon.
                                         
                                         You have no idea whether it's
                                         
                                         simply rendered as a coroutine or
                                         
                                         as a normal
                                         
    
                                         traditional function. It's simply
                                         
                                         implementation detail. You can flip back
                                         
                                         and forth.
                                         
                                         So why did I go there?
                                         
                                         Oh, I know, I know, I know. I was
                                         
                                         going for explanation
                                         
                                         why correturn is actually useful.
                                         
                                         Sometimes you just want to write
                                         
    
                                         a do-nothing coroutine, essentially,
                                         
                                         that it never suspends.
                                         
                                         Maybe you just started typing it.
                                         
                                         So you can say correturn semicolon,
                                         
                                         and boom, your function is a coroutine.
                                         
                                         Or maybe correturn space 42. So, thus, function is a coroutine. Or maybe correturn space 42.
                                         
                                         So
                                         
                                         thus you have a coroutine
                                         
    
                                         and it doesn't require extra tag.
                                         
                                         So that particular usage of
                                         
                                         correturn made me less
                                         
                                         annoyed with co underscore.
                                         
                                         Okay, so what
                                         
                                         is the difference between
                                         
                                         a function that always returns
                                         
                                         the same value and a coroutine that always returns the same value?
                                         
    
                                         I mean, like, if you just did co-return 42, like you were just saying.
                                         
                                         Well, the function will be identical.
                                         
                                         Because coroutine is simply, no, that way around.
                                         
                                         Function is a special case of coroutine.
                                         
                                         Okay.
                                         
                                         So coroutine can do everything that a function can do,
                                         
                                         but better.
                                         
                                         It can do more things.
                                         
    
                                         But when it is doing exactly the same thing as a function,
                                         
                                         it is a function.
                                         
                                         Okay.
                                         
                                         And that is something that I am trying to,
                                         
                                         let me see, break consensus.
                                         
                                         So coroutines were absolutely awesome
                                         
                                         60 years ago, in 58,
                                         
                                         because they were understood
                                         
    
                                         as a better function, as
                                         
                                         more general
                                         
                                         form of a function. But then
                                         
                                         after our goal 60,
                                         
                                         stacks came around, and
                                         
                                         block-scoped variable came around.
                                         
                                         And those were hard to implement
                                         
                                         without extensive compiler support.
                                         
    
                                         So people took an easy route.
                                         
                                         They implemented coroutines on top of user-mode scheduled threads.
                                         
                                         And that is a much heavier abstraction than a function.
                                         
                                         And at some point, people start calling user-mode scheduled threads or fibers.
                                         
                                         They start calling them coroutines.
                                         
                                         Then they start disambiguating them with, oh, it's a stackful coroutine,
                                         
                                         and whatever is not a thread, it is a stackless coroutine.
                                         
                                         But essentially, those are two different things with very different costs of usage costs.
                                         
    
                                         And right now with compiler-supported coroutines,
                                         
                                         we're bringing those good coroutines of the old,
                                         
                                         which are generalization of functions back. And usage of coroutines as a cheaper thread is less.
                                         
                                         Okay, so if
                                         
                                         you today, when you're writing code, do you just
                                         
                                         use coroutine,
                                         
                                         coreturn, you know,
                                         
                                         like, do you take
                                         
    
                                         advantage of the fact that coroutines are
                                         
                                         a better function and just use them
                                         
                                         everywhere?
                                         
                                         No, because usually because there is
                                         
                                         potential suspension involved,
                                         
                                         you
                                         
                                         probably have a different type
                                         
                                         that we use normally.
                                         
    
                                         So if it's a generator,
                                         
                                         you likely use some generator type
                                         
                                         and you want to yield.
                                         
                                         So
                                         
                                         if it's future,
                                         
                                         if you used to write a function
                                         
                                         that returns a future,
                                         
                                         you can switch to using coroutines trivially.
                                         
    
                                         But if your function never suspends,
                                         
                                         why do you want to return a future of int
                                         
                                         or some equivalent of future of int
                                         
                                         as opposed to plain int?
                                         
                                         Right, okay.
                                         
                                         You were talking about threads a moment ago.
                                         
                                         Is there any interesting interactions
                                         
                                         between coroutines and threads that we should know about?
                                         
    
                                         Well, if you implement an asynchronous coroutine,
                                         
                                         the one with square weight,
                                         
                                         which is trying to represent some async activity,
                                         
                                         well, it's your choice or the choice of the library writer
                                         
                                         whether you will be resumed on the same thread some machine activity, well, it's your choice or the choice of the library writer whether
                                         
                                         you will be resumed on the same thread as the one that got suspended or a new thread.
                                         
                                         And you have to be careful there.
                                         
                                         And some people prefer to be resumed on the same thread and that can be encoded in the
                                         
    
                                         await adapters, which tells the compiler what to do when await happens.
                                         
                                         But it might be surprising.
                                         
                                         TLS is one of the things which might switch when you go to a different thread.
                                         
                                         So if you read something from TLS, when you resume slightly later, you will be reading
                                         
                                         from a TLS for a different thread.
                                         
                                         So for our listeners who are familiar, you're referring to thread local storage.
                                         
                                         Yes. So you're saying if you have a thread local object in your
                                         
                                         coroutine, you access that, somehow return it, whatever,
                                         
    
                                         and then the next time your coroutine is resumed, it's from a different thread,
                                         
                                         you're going to now have a different local state that you weren't expecting to see, effectively.
                                         
                                         Yes, you will be consuming
                                         
                                         the thread local storage from
                                         
                                         whatever thread is currently running.
                                         
                                         Interesting.
                                         
                                         Which is actually wonderful.
                                         
                                         Which is wonderful, because
                                         
    
                                         let me tell you what happens
                                         
                                         when it's the other way around.
                                         
                                         So, like,
                                         
                                         you know there are fibers, there is
                                         
                                         boost coroutine,
                                         
                                         so compilers, in some architectures, thread local access is expensive.
                                         
                                         So they would go and cache an address of a TLS page in some of the registers,
                                         
                                         which are preserved between function calls. And then imagine that
                                         
    
                                         you suspended
                                         
                                         that function
                                         
                                         in a stackful manner, which essentially
                                         
                                         means you have no idea that you
                                         
                                         got suspended, because some function
                                         
                                         10 levels down
                                         
                                         didn't suspend.
                                         
                                         And then you resume the coroutine
                                         
    
                                         on a different thread.
                                         
                                         So now that register points potentially into some other memory.
                                         
                                         So it is actually very dangerous not to do what happens in the C++ coroutines with regard to thread local storage.
                                         
                                         Right.
                                         
                                         So essentially with things like boost coroutine, if you resume your stackful coroutine on a different thread,
                                         
                                         it is undefined behavior if you touch thread local.
                                         
                                         Like you should not touch thread local at all.
                                         
                                         Okay.
                                         
    
                                         So I just want to make sure I understood one thing.
                                         
                                         If you're running a GUI application and you call a coroutine
                                         
                                         and you want to make sure
                                         
                                         you resume on the UI thread, is that something
                                         
                                         you can do? Yes.
                                         
                                         And what does that calling syntax
                                         
                                         look like?
                                         
                                         It's all the same. It's call await
                                         
    
                                         on something. And since
                                         
                                         it is the library that
                                         
                                         describes to the compiler
                                         
                                         what happens when you call await,
                                         
                                         you can do things like you capture the current execution context,
                                         
                                         which threads you are running,
                                         
                                         and then when you resume the coroutine,
                                         
                                         you will simply say resume on that thread.
                                         
    
                                         But it depends on your environment.
                                         
                                         So coroutines were made to work with arbitrary runtimes.
                                         
                                         So as long as you can express that in your runtime,
                                         
                                         you can teach coroutines to interact gracefully with it.
                                         
                                         So coroutines come naked.
                                         
                                         It's just a compiler feature.
                                         
                                         But by design, it was meant to plug in
                                         
                                         to whatever asynchronous runtime you have
                                         
    
                                         or UI runtime.
                                         
                                         So do you think that coroutines are going to fundamentally change
                                         
                                         the way we interact with C++?
                                         
                                         Only if you do async stuff, maybe UI.
                                         
                                         And it will be easier to write iterables.
                                         
                                         So, like lazy sequences, it's another use case.
                                         
                                         But it's mostly, I think, those two.
                                         
                                         Asynchronous programming and lazy sequences.
                                         
    
                                         But otherwise, you'll be doing exactly the same way like before.
                                         
                                         Well, maybe one more.
                                         
                                         Coroutines also allow you to write clean code without exceptions, because
                                         
                                         every await point can be customized to work like if error go to end. So, for example,
                                         
                                         if you have expected of t type, which expressed either a value or an error, you can make so
                                         
                                         that when you co-await on expected of t, if it contains a value make so that when you co-await unexpected of t,
                                         
                                         if it contains a value,
                                         
                                         the result of the co-await expression
                                         
    
                                         will be just t,
                                         
                                         whatever that value is. But if
                                         
                                         it is an error, it will propagate
                                         
                                         as the
                                         
                                         return value of the entire function,
                                         
                                         of the entire coroutine.
                                         
                                         So this is another use case.
                                         
                                         Interesting. Yeah, it was, I think, of entire core routine. So this is another use case.
                                         
    
                                         Yeah, it was, I think,
                                         
                                         we had five design goals.
                                         
                                         Scalable, efficient,
                                         
                                         interact with C gracefully,
                                         
                                         open-ended, meaning customizable to whatever on time.
                                         
                                         And the last one was exceptions are optional.
                                         
                                         Interesting.
                                         
                                         Definitely some people who would be interested in that.
                                         
    
                                         Well, like driver writers
                                         
                                         we didn't want to make
                                         
                                         coroutines tied to the
                                         
                                         exceptions in any way
                                         
                                         we can interact with exceptions just fine
                                         
                                         but you don't have to
                                         
                                         and because of that property you can actually
                                         
                                         express something like
                                         
    
                                         exception like nice
                                         
                                         clean control flow
                                         
                                         because all of the error
                                         
                                         propagation will be handled
                                         
                                         under the covers by the library
                                         
                                         machinery that you explain
                                         
                                         to the compiler what happens
                                         
                                         when you go and wait on expected of T
                                         
    
                                         or maybe an optional of T
                                         
                                         or whatever you want.
                                         
                                         Okay.
                                         
                                         Well, Gor, I think we may have gone over everything.
                                         
                                         Is there anything else you wanted to bring up
                                         
                                         before we let you go?
                                         
                                         Well, one thing.
                                         
                                         Rob is actually doing the intro to the CppCast live
                                         
    
                                         because I thought it's always the recording
                                         
                                         because it was so, so, so identical every time.
                                         
                                         And now I'm seeing it live.
                                         
                                         It is incredible.
                                         
                                         Well, Gore, thank you so much for your time today.
                                         
                                         It's been great having you on.
                                         
                                         Thank you, guys.
                                         
                                         Thanks for joining us.
                                         
    
                                         Thanks so much for listening in as we chat about C++.
                                         
                                         I'd love to hear what you think of the podcast.
                                         
                                         Please let me know if we're discussing the stuff you're interested in. Or if you have a suggestion for a topic, I'd love to hear what you think of the podcast. Please let me know if we're discussing the stuff you're interested in.
                                         
                                         Or if you have a suggestion for a topic, I'd love to hear about that too.
                                         
                                         You can email all your thoughts to feedback at cppcast.com.
                                         
                                         I'd also appreciate if you like CppCast on Facebook and follow CppCast on Twitter.
                                         
                                         You can also follow me at Rob W. Irving and Jason at Leftkiss on Twitter.
                                         
                                         And of course, you can find all that info and the show notes on the podcast website
                                         
    
                                         at cppcast.com.
                                         
                                         Theme music for this episode
                                         
                                         is provided by podcastthemes.com.
                                         
