I cannot express how delighted I am about the pedagogical skills of Timur Doumbler. In each conference I am looking how a speaker/teacher introduces a new material. The latter should usually be a solution to a problem or a better way of solving a problem than the already existing ways of doing so. And what Timur is doing is that he is going to the problem or to the needs, first. Second, he is proposing iteratively different better and better existing solutions to the need/problem and then finally finally he shows WHY the need for this new feature/solution appeared. Almost noone is doing this - "before talking about modules, we should first talk about headers". Almost noone is the pedagogue that a speaker/teacher should be - to talk problem-first not solution-first. What provoked that solution? The brain is a associative device - neurons and links between them. If you cannot provide a link for the new material to an existing knowledge of the listener, then the latter would have harder time understanding the new material. Going problem-first establishes/builds that associativity bridge to the new material. Look at some of the other CppCon sessions and turn your attention very carefully to how new language features are presented - almost every time solution-first. Why those features were created? What motivated their birth? Praise for the Timur's pedagogical skills and the energetic way he speaks and engages the listener.
@piotrarturklos4 жыл бұрын
This is an excellent user-level summary of coroutines among other things. Also, the talk really delivers on the promise of the title.
@isleofdeath3 жыл бұрын
YES, finally concepts! All in all, C++ is becoming more and more functional. I love that. Moving from overloaded OOP to functional expressions is a good step imho.
@KarlBrouillette4 жыл бұрын
Thank you! I haven't worked with C or C++ in over 20 years but was recently thinking of reacquainting myself with it. Watching your video has made it much more compelling.
@klauselk4 жыл бұрын
Not an easy task Timur has taken here. He wants to tell us how "end-user" code will change with C++ 20, but also wants to explain why things are as they are. This leads into too much about the implementations behind it all - at least for me. Especially the Coroutines part becomes very complex. The Concept part has a bit of the same, because its also about how library code will change. It really shines when he gets to the Ranges. The last major subject is Modules, which we have seen in other languages for a long time, so not hard to understand. Thanks for all the hard work!
@ILoveSoImAlive3 жыл бұрын
You can read about this topic in the context of javascript. There you have all the yield, async await, closures, promise explanations in a way, even frontend dev can understand them 😁. In short: its about abusing nested function definition and the fact that the scope of the outer function is visible inside the inner function, even after the outer function was thrown from the stack, because of relative adresses to the local vars of the outer function from the inner functions perspective, so that you can use outer function, which is unreachable after the first execution from outside, as a container for the state of the inner function, which you can use by reference, after you got it as return from the first execution of the outer function; and about syntax to work with async callbacks without getting braindmg, by defining objects wich can be used to kick start a process and to define what should happen after you got an async answer per callbacks in any constelation (one, all, first). Something like Promise p1 = getFromDB(cb1) {...} Promise p2 = getFromFile(cb2){...} Data localDataStruct Promise.first({p1, p2}).onDoneDo({localDataStruct = retData;}).onErrorDo({localDataStruct = defaultData;}) print(localDataStruct) Realy handy. Imagine writing that without promises.
@michaelkovaliov8877 Жыл бұрын
If a C++ standard comitee member had to take a full day of work to use a feature of the C++ 20 language you can just tell how half baked some of the features of this language are. I really struggle to love C++ lately
@zhaoli29844 жыл бұрын
It is time to consider to generalize the optimization coroutines have to other objects. The compiler is allowed to do escape analysis, and it is free to eliminate heap allocation of a coroutine if it can prove it never escapes a scope. This optimization should be applied to other C++ objects. Many short-lived objects should not incur heap allocations.
@rudolflovrencic4 жыл бұрын
35:40 Can't we achieve this by using C++17 "if constexpr"?
@adamodimattia4 жыл бұрын
Wow, coroutines! Amazing... :D but what a dissappointment though.... the big anouncement of the c++20 feature that is not even fully implemented yet :(
@JeanNoelAvila4 жыл бұрын
4:40 "we had to change to the paper size to a standard ISO, from US letter to A4"... ROFL. For an ISO standard, it's never too late.
@bagolzz4 жыл бұрын
22:42 What's the point of introducing an incomplete feature into the language? I'm all for concepts and modules (if modules ever get properly implemented in compilers...), but why would anyone use coroutines if they had to add yet another external library for it to work, just to have it replaced in C++23? It's not like coroutines solve something that was impossible so far and I'd argue that the alternatives are much more readable anyway.
@tomaszwozniak76834 жыл бұрын
Great, concise talk, as expected from Timur
@SamWhitlock4 жыл бұрын
Those explanations of SFINAE and what a hack it is is so on point. I had no idea about the issues with "colliding" function templates like in the is_power_of_2 example!
@TheMR-7773 жыл бұрын
Thank you for Presenting "The Big Four of C++20". It's the first Presentation I ever saw on CppCon, and I am absolutely motivated to attend more. Thanks a lot again!
@CppCon3 жыл бұрын
You're very welcome!
@Johnkank4 жыл бұрын
Great Talk. I really liked the way you compared the current to the new c++20 style. I especially liked the Coroutine part as I had trouble understanding the inner working.
@josiethompson57392 жыл бұрын
Wow, seriously an incredible talk! Make it a book and I'll probably even buy it!
@4otko9994 жыл бұрын
30:00 this is pretty cool, but how do you move f2() to another thread? Should it start its own thread and yield from that?
@jhbonarius4 жыл бұрын
Hmm he explains how we don't want an iota lambda object, as we don't want extra objects. Then he shows how coroutines have promise objects, have to be allocated on the heap and has its own persistent state. Sounds like solving a problem with more problems.
@johnnyserup55004 жыл бұрын
not really, he also talked about how the compiler/linker will be able to optimize better
@NomoregoodnamesD83 жыл бұрын
a counting generator is an overly-simple coroutine. You could implement a state machine's update function as a coroutine, and call the coroutine until the state machine is done. Or better yet, create one of these coroutines, use it a bit, then pass it to someone else to continue using. This sort of thing would normally require macros to create in C/C++ (those macros wrapping around setjmp and longjmp and also case labels and goto), and the function frame might have to go on the heap regardless, unless you decide to allocate space on the stack manually for data.
@Fetrovsky2 жыл бұрын
Starting on 15:30: you go from "this is not C++" to "we now have this and there's a whole bunch of stuff" without really building up the why those things are necessary.
@arun_govind4 жыл бұрын
A great introduction and need good compiler and IDE to start exploring further
@RandalKoene4 жыл бұрын
Nice to have generators... conceptually very familiar if you just think of them like file handles or sockets with a server behind it that offers you a response each call. Writing a generator is like writing a tiny server.
@Megalcristo23 жыл бұрын
Or a template (literally not the c++ feature) function with memory/states
@vit.khudenko4 жыл бұрын
I am not a C++ developer, but still it was an interesting stuff. Thank you. From what I've just seen the C++ lacks (IMO, of course) a human friendly syntax. Even with the recent improvements it looks to me too cryptic and verbose.
@jhbonarius4 жыл бұрын
Your looking at the worst of it. Coroutines are just new and required some structural changes in the language, introducing new keywords and so. And the supporting framework is not there yet, so everything is very verbose and overly complex now.
@openroomxyz2 жыл бұрын
Are corutines faster than using static, or lambda? How are static variables inside functions accessible outside the function?
@Sbence924 жыл бұрын
I just cannot understand coroutines. It's the most complicated language feature and it solves a problem that's hard to have a mental model for. Maybe it'll become easier, but every talk and article says this is quicksand, beware, use coro (nonstandard), don't try at home and I start to think this feature went sideways somewhere. Do I have the wrong impression?
@ctrlaltdebug3 жыл бұрын
Look up the old switch-based coroutines, "Duff's device" for the core concept. The C++20 coroutines appear over-engineered, as if they were designed by committee.
@kiseitai23 жыл бұрын
I feel the same way. lambdas was the first thing that came to my mind for tackling the same problem and feels like it should have been the syntactical approach and model. I don’t think the performance improvement will be worth the trouble as opposed to simply use a lambda.
@eduardovillasenor61114 жыл бұрын
This is such a nice talk , thanks Timur Doumler !!!
@QBziZ4 жыл бұрын
A function template that needs to discern between integer and floating point could also use "if constexpr"
@TheMR-7773 жыл бұрын
I did the same to check whether am I right or not :), and I was absolutely stunned by the successful results!
@DrunkenUFOPilot Жыл бұрын
The std::erase() example is *so* elegant! I'm sold on c++20. Buh-bye C==17.
@them43094 жыл бұрын
so how is "creating a function pointer that holds a template co_yield magically returning static but not-global variables using goto but not calling it goto" better than a "for loop"?
@UsatiyNyan4 жыл бұрын
Because context switching is one of the requirements for coroutines, which are essential to have in HighLoad applications. By the way, if you would look at some of the usages of generators in python you would definitely see the necessity of them in many different tasks.
@nicholasgilmet23534 жыл бұрын
10:30 "making a class for this is kinda overkill" 14:45 "it returns an object" I don't see how this is a new feature. It just looks like a more confusing way to do something that was already possible.
@tamrix4 жыл бұрын
It generates the values lazily and returns control of the execution to the callee each time.
@totof28934 жыл бұрын
@@tamrix the functor and lambda as well are doing lazy generation of value during operator() and return execution to callee at the end of operator()
@wizardy62674 жыл бұрын
class is overkill, but promise + coroutine_handler + coroutine_frame are cyclekill meaning they kill like an infinite loop~
@deanroddey28813 жыл бұрын
Every example of why coroutines are useful tends to just demonstrate why the thing it is replacing is simpler and more obvious and doesn't suck a bunch of complex infrastructure into your program and make it harder to reason about.
@loggyaltsen81912 жыл бұрын
Is there still a compiler for c++20? I am a Mac user can’t find one.
@hanyanglee90182 жыл бұрын
The real different between generator(with yield, in many other languages) and functor is that, with out this new suger, a generator looks like: class Gen{ int step{0} Gen(something){ something} auto operator()(something){ switch(this.step){ case 0: do something this.step = 1; return something; case 1: do something this.step = 2; return something; case 2: do something this.step = 0; return something; }}} But with this suger, the whole structure is simplified to almost the limitation as you've already seen a lot of times in many other languages. Idk if the yield tech use any feature directly from instruction set from cpus. Even that is the case, the performance should basically be the same.
@akj73 жыл бұрын
55:50 What about namespace {}?
@zhaoli29844 жыл бұрын
About that function "is_power_of_2", a simpler solution is just adding a plain function overloading which takes double.
@ytubedecharly3 жыл бұрын
He actually shows that approach on a slide. The problem is you are not doing generic programming anymore and have to patiently write all the necesary overloads.
@sotirissalloumis61294 жыл бұрын
Thanks for sharing, a very interesting and informative presentation.
@UsatiyNyan4 жыл бұрын
59:54 Actually it is basically the same operation BUT! it is faster and it works in O(n) while moving elements to the end works in O(n^2) in the worst case. But the frustration is pretty understandable.
@rauldragu94472 жыл бұрын
Both algorithms have the exact same complexity, O(n). Moving the unwanted elements to the back while also preserving the relative order of the wanted elements, as does std::remove, can be trivially implemented linearly. The only potential, and standard library implementation dependent, improvement that std::erase could achieve would be to call the destructors of the removed elements inline, in a single loop, instead of calling them in a second, sequential loop, as is v.erase(std::remove(...), v.end()) forced to do.
@porky11184 жыл бұрын
at 39:14 you could also use typeof, so you don't require template, right?
@konsth1912 жыл бұрын
That last code slide confused me a bit, but it seems like it works with std::erase_if instead of std::erase!
@chiefsittingstill60612 жыл бұрын
Yes, I got caught out on that too. Trying the functions out, I've found that std::erase erases any value in the collection that compares equal to a specified value, whereas std::erase_if erases any values in the collection that match a predicate (as per this last code example).
@silverqx3 жыл бұрын
Thank you Timur, I learned few new things here 🙏
@CppCon3 жыл бұрын
Glad it was helpful!
@silverqx3 жыл бұрын
@@CppCon I would welcome the same type of video for c++23 😁, but it is too early of course, it will be actual in few years. 🙌
@karabitski22 жыл бұрын
Great introduction! Thanks.
@CppCon2 жыл бұрын
Glad you enjoyed it!
@venkateswarans10123 жыл бұрын
C++20 book to refer ?
@Marlon-ld2jx3 жыл бұрын
Very good explaination
@davidconnelly3 жыл бұрын
I don't have a clue what he was talking about. I mean, pretty much none of it. It's not him. It's me. I've only been looking into c++ for about a week or so. The problem I have is that all of the training I can find talks about things like creating; creating variables, classes, for loops etc. I cannot find any training that covers some of these more advanced topics. I'm also struggling to find training that walks you through actual projects. I mean, building apps. Could anybody out there please direct me to an authoritative book or course that will help me to get up to speed with some of this more advanced stuff?
@divad11964 жыл бұрын
I wonder what is the performance (memory and speed) of coroutines against simple lambda version as shown at the beginning (when it can be compared). And secondly, for async_generator, if we don't wait for the computation, when will it be done?
@llothar683 жыл бұрын
They are the same. The implementation code is almost exactly the same for both. There is just one instance pointer more in the heap object that holds the next enter address. Therefore it's an indirect instead of a direct jump. And one at the yield to store the address. But thats interleaved with the superpipeline and has zero cost.
@programmingeverything4 жыл бұрын
very good talk and also love these changes!
@quantumac4 жыл бұрын
As a long-time programmer who wrote C/C++ for many years (now retired), I thought lambda functions were much too "clever" for my tastes and not easily maintained. I think lambda functions make code much harder to read. By analogy, a lambda function is like a mid-roll ad on KZbin. You're reading one function and then all of a sudden you're reading another function and then back to the original function. Syntactically, it's also very confusing. Each new C++ standard seems to enable new features which make it even more cryptic and harder to read than the previous iteration. Instead of introducing new reserved words, new versions of the language seem to concentrate on creating new combinations of special symbols already used by the language, reusing them in odd ways. Yes, it's all very clever, but shouldn't readability be a desired outcome as well?
@VenelinEfremov4 жыл бұрын
Like many great tools Lambdas are not immune to abuse. I think people can write unreadable code in any language. I've seen lambdas within lambdas within lambdas in TypeScript and Java and they are all atrocious. It is up to the code maintainers to keep the codebase sane. The language alone is not going to enforce that.
@jeorito4 жыл бұрын
I mean it really depends on what you're trying to do with a lambda function? if you only need a function to detect if certain number is odd number or not and only using this once and no-where else.. it's just cleaner with lambda function for my taste. That being said from pure readability stands point, i think you're correct
@Stanniemania4 жыл бұрын
Other perspective here: I've been programing in C# as a day job for 4.5 years now (and doing C++ simultaneously for the past 2 or so) and have basically grown up with lambdas. Being able to use them in C++ too is absolutely awesome. Passing simple predicates to functions like std::find_if (or some library like cpplinq) is waaay more readable than binding it to some other function many lines down or up. Such predicates are mostly very short, often not more than 2 or 3 lines. My experience is that if they make code hard to read then it's not the right place to use them. If the body of your lambda is so long that it distracts you from the code around it, that probably means the logic is also more complex than a simple predicate. Then indeed do extract it to a different function. Example: { vector things{}; const auto firstValidThing = std::find_if(things.begin(), things.end(), [](cosnt auto &x) { return x.IsValid(); }); } IMO this is totally clear. Heck, even if I'd extract it the I'd still call that function from a short lambda because I find the lambda less tedious than the bind syntax.
@aurelienrb4 жыл бұрын
From what I've seen, all people working on the evolution of C++ are well aware of those aspects. But simplicity is a very difficult thing to archive. And by introducing new keywords, you are not solving the complexity issue but simply moving it elsewhere. And you will still get people to explain how crazy the language is based on the great number of keywords it contains and so on. Many people wonder why not making things simpler, until they start to propose something and get feedback. Then they start to discover subtle details they didn't have in mind and make it not feasible that way. So it's not why not make it simple, but how. Feel free to help the community in that direction 😀
@leoalmeida25833 жыл бұрын
Lambdas captures is something that a normal does not support. Suppose that you want to pass a predicate to an algorithm but the predicate itself depends in a local variable that is not passed as argument. How would you solve this problem? Before C++11 you had to write a functor for it. Cannot see my self program in non modern C++, things became much easier now.
@jaybny Жыл бұрын
awesome!! thank you
@ajmgdaj2 жыл бұрын
Really cool. Yet, I have a bit of a problem with the first 30 minutes being a teaser trailer for a feature that is clearly not usable yet. It even ends with an endorsement of a library whose main branch on github does not build (let alone pass a test suite), at the time of this comment. As I know what coroutines do to your code, seeing it is not all pretty and knowing it twists and turns several thinking processes about how to write code pretty painfully (well at least for me) on their heads, committing to an unfinished unsupported feature like this would be a mistake... ironically exemplified by this otherwise great talk.
@Megalcristo23 жыл бұрын
37:50 why don't just use a template specialization?
@tomaszmaachowski23033 жыл бұрын
Thought the same
@leoalmeida25833 жыл бұрын
He would have to specialise for all int*_t and double, no?
@weekipi5813Ай бұрын
Only thing I hate about this new updates is the introduction of modules, it seems like the committee are liking JavaScript modules so much so they want c++ to look the same
@about2mount10 ай бұрын
You do not need Coroutines or Globals. Why? We do this: void index_it(int& cnt, int& swt){ cnt++; swt = 1; }; int main() { int count = 0; int switch = 0; index_it(count, switch);
@blazkranjc914 жыл бұрын
Thanks for a great talk! I would argue that the order of the presented features is slightly strange and the allocated time per feature could be allocated differently, but it is nice to see c++20 making even the slide-ware so much better!
@nikylenguyen59504 жыл бұрын
I'm glad that C++ is becoming more like JavaScript/TypeScript on the surface. Looks much cleaner and more productive. There are always gotchas, but at least there is a clean/less-verbose coding style to stick to in order to avoid headaches for those of us who are not deeply interested in the language but just want a straightforward way to implement the business logic where C++ is the constraint.
@treyquattro4 жыл бұрын
A co_routine is a function combined with a fiber
@alexanderilich37364 жыл бұрын
This is the way
@maximchetrusca33012 жыл бұрын
So coroutines are there, but not yet there, as we need a generator... Pure C++-way of doing things :)
3 жыл бұрын
C++20 compared to C++98 is supercharged and a whole different experience.
@Ikkepop11 ай бұрын
Why are coroutines designed in a such a complex way that even an expert can barely use them...
@EgorChebotarev6 ай бұрын
nice
@goldnoob61913 жыл бұрын
Realy the turn in C++ has been template meta programming. All evolutions of the core langage is aimed towards templates. C++14 is the inflection point, anything following is just bug fixes 😅. Anyway there is more to come, I've been pissed already when trying to implement various flavors of the state pattern.
@B0JACK3 жыл бұрын
I don't like coroutines, to me it just looks like the class example :(
@llothar683 жыл бұрын
I really want modules, no more pimpl workarounds. And coroutines.
@diconicabastion57903 жыл бұрын
Honestly the coroutine seems to be a waste. Notice first it isn't just called a function because it no longer is just that. Secondly, It seems like all they are doing is hiding the class/object construction. I can honestly say here and now I'll never use it. I see this as causing more confusion over time vs the number of problems it solves. Concepts and ranges seem ok. Not sure about modules that much. Probably because the use case he described it for. If I had multiple files using the same headers. I'd set the headers into a single header file then simply include that one header file in each of those files. They are still independent and it reduces compile time.
@Silverfields14 жыл бұрын
What a disappointing example of co-routines; the worst of all presented solutions to his example problem!
@danielc42672 жыл бұрын
Can you give us a good example? Or share a link that has it?
@alexkfridges2 жыл бұрын
What a disappointing take away from the illustrative example
@glennstockton65774 ай бұрын
Not ceen ñothing yèt
@MsJavaWolf7 ай бұрын
I don't get why people hate loops so much.
@indrajitghosh41873 жыл бұрын
Somehow a functor seems a hundred times simpler and more intutive than a coroutine and generator to me. I wonder if coroutines are going to be one of those esoteric features that only a few really use..
@jankopiano577 Жыл бұрын
Addtionally, using a class as a generator means you can give it a reset() method to restart it, or swap out its internal state to return it to any previous state. You can also guarantee that a class can be on the stack. Can you do all those with a coroutine?
@aitorsanmartin14 жыл бұрын
I do not understand why do we need this corutine stuff to be honest? please can someone give me a real life usefull example? because for me looks like complicating the things more than necessary, when you can just write a loop or whatever, which looks simple to reason about and less code to write.
@sebjan1804 жыл бұрын
The example he used wasn't great as basically all of the solutions he presented (apart from the static) were pretty decent. Typically, the benefit would appear better when you have multiple yields. Imagine, for instance that you'd want to generate a sequence like 1,2 ... 9, 9, ... 9, 8 ... 1. This would require a rather messy state machine for the other methods, but easy to write with yield. The other great benefit is of course the await part that he touched just lightly upon, but if you have experience with javascript or C# you might already know of their usefulness. Basically it removes the need for callback chains which can greatly increase readability in some cases.
@robertgernert84814 жыл бұрын
The real life example that I long for to be solved by coroutines is very related to callback hell. In my problem there are two cloud services that I need to ask for data. The output of the first is partly forming the second query. The problem that I have now is that it is hard for colleagues to get an overview of how the component is working. The main thread of doing things is scattered over a couple of functions. There have all nices nice names and types and stuff. But still, there is a considerable cognitive load to figure out what the next step is while remembering what the previous step was. Coroutines give me the possibility to express the main idea of the component in one screen. For understanding the idea of the component it is not necessary to understand how coroutines work. That's great because I can still read the parts that are interesting.
@kostaad3 жыл бұрын
cpp 2020 = c# 2013
@gnarfgnarf40043 жыл бұрын
I fail to see the benefit of coroutines. It just sounds like a non-reentrant mess. What if the same function is called from two different places? Modern C+ is like a guy who has dug himself into a deep hole, and is bragging that he now has a chrome-plated shovel. With a fur-lined handle.