How C++23 Changes the Way We Write Code - Timur Doumler - CppCon 2022
Vložit
- čas přidán 10. 03. 2023
- cppcon.org/
---
How C++23 Changes the Way We Write Code - Timur Doumler - CppCon 2022
github.com/CppCon/CppCon2022
C++20 was a huge release: coroutines, concepts, ranges, and modules profoundly changed the way we write code and think about C++. In comparison, C++23 is a lot smaller in scope: its primary mission is to complete C++20, to fill holes, and to fix issues. Nevertheless, some great new features made the cut this time around, both in the standard library and in the core language. This is even more remarkable considering that the entire feature design phase of C++23 took place during the COVID-19 pandemic, challenging the ISO C++ committee to completely reinvent how we work together.
This is not a firehose talk about C++23 that tries to cram as many additions and improvements as possible into one hour. Instead, we deliberately focus on just a handful of new features that are going to noticeably change and improve the experience of the everyday C++ programmer. We will talk about how `std::expected` improves error handling, the huge impact that `std::mdspan` will have on scientific computing, how deducing `this` greatly simplifies longstanding C++ idioms such as CRTP, and how `std::print` will forever change how we write "Hello, World".
---
Timur Doumler
Timur Doumler is the Developer Advocate for C++ tools at JetBrains and an active member of the ISO C++ standard committee. As a developer, he worked many years in the audio and music technology industry and co-founded the music tech startup Cradle. Timur is passionate about building inclusive communities, clean code, good tools, low latency, and the evolution of the C++ language.
---
Videos Filmed & Edited by Bash Films: www.BashFilms.com
CZcams Channel Managed by Digital Medium Ltd events.digital-medium.co.uk
#cppcon #programming #coding - Věda a technologie
2023: the year when somebody proudly presents a print function in C++
Kinda sad if you think about it, but I guess that was the point of your comment too.
It's really nice replacement for printf, which i still use when i need something better than cout
There was no print function because there wasn't a way to keep them type-safe. std::cout was type-safe and thanks to compile-time evaluation features a print function could be type-safe as well. So they added it.
As usual, long after every company developed their own version of formatted print, the standard comes with another one. The legacy code becomes annoying, you need to remember two ways of doing the same.
Finally I can print "こんにちは" without exploring 4D web spaces from day to fay
16:49 at this point I imagined Timur removing these features one by one, and then finishing the talk and asking the audience if there are any questions 🙂
Q: "So what WILL change the way we write code?"
Timur: "Rust." 😎
amazing, finally i can stop explaining what "cout", "
16:54 is where the removal of stuff from the list ends and C++23 feature explanations start.
Please, @CppCon, add chapters to the talks.
Wow. The CRTP simplification is simply amazing.
Yes. The fact that you don't need to write the base class as a template and you don't need that static_cast is just great. The syntax looks a lot cleaner. I remember when I was first learning about CRTP it seemed like black magic to me. Deducing "this" is probably my favorite feature from c++23 right now
You guys see how many HATERS there are in these comments?!? Like what in the actual eff, CRTP is like one of the most important patterns in the entire language, and now it's elegant and easy to use? WTF!? Best feature in all of C++23. They're crazy!
you do still need the template parameter if the mixin contains a field relating to the actual type (for example enable\_shared\_from\_this contains a weak\_ptr, so it will continue to need the actual type), but yeah it's still really nice to have and i'm very sad that this feature is implemented in neither gcc or clang yet
It's not a simplification tho, is half as powerful as real CRTP
Timur as always made a great and useful talk! Thank you, I love the way you make your presentations!
Thank you for this talk, Timur. It was really the cool one.
Timur has greatly strengthened his speaking skills. Good job!
A truly fascinating lecture, start to finish!
Clicked on the video to see what's going with C++ these days....stayed for the comments LOL
The dynamic multidimensional c code.... its beautiful, all of it :D
Really cool talk. The one thing that was missing from std::expected was a quick mention of the monadic functions that come with it. In my experience, these make working with std::expected much easier than first thought, especially if you have/want to use it across a larger call stack and to compose multiple functions that return a std::expected.
Great talk, thank you!
Regarding std::expected, it will be possible to create a "std::expected coroutine" that uses the coroutine customization points to hide explicit error checking logic using the co_await keyword.
Starts at 15:45
Still waiting for it to start…
Wow. The whole video should just start there.
Great talk!
I loved this talk.
At 1:00:00 this is what I needed in C++ for really long time. 👍
I am so grateful that I get to program in D!
I didn't know this language was actually used somewhere. Good to know
I hope one day we will get the same syntactic sugar as Rust with Result, where we use "?" to access the internal value or directly return the error.
It would avoid all the boiler plate code of checking the status when you don't want to do anything specific but propagate the error.
There's a proposal about this!
It should be possible to implement with a macro.
I think with GCC statement expressions and omitted ternary operands it's very easy, you should be able to write a macro like: #define Q(X) ( X ?: ({ return X; }) ), although I haven't tested it. This would allow you to write Q(expression) with the same effect as expression? in Rust
EDIT: Actually, there's an issue with the "return X" part, it will do side effects twice. So instead of a ternary we would need some kind of statement expression that stores X temporarily. The problem is how exactly to store it, since it could be a non copyable or moveable (or non-trivially copyable/moveable) type
Really cool talk as expected from Timur Doumler but I think there would have been time to talk through half of these features just in the time he took to widdle down the list.
Reading this comments ... i think Cpp needs to be completely remade lol
With `deducing this`, can we have a better `shared_from_this`? If I enabled it in a parent class and want to use this in any inherited classes, I have to use `static_pointer_cast` which is fine but kind of annoying.
At 34:10 I was expecting a Y conbinator or something similar. You could just wrap f in a few more function closures to get rid of having to pass the function around
It feels like we are only a decade away to get string interpolation as a lang feature (no other way around, itneed compiler magic). Brigth future is ahead
I really like all four highlighted additions.
Now would be good time to finally add some bool has_key() method to standard hash containers, so we don't have to write lookup + result comparison for such a basic operation.
Or, make it so that compiler error output doesn't always display all default template parameters, unless the code explicitly specifies non-default value. If the code works with std::string, compiler error could just say that (at least in some cases?), instead of std::basic_string.
Since C++20 all of the associative containers are standardized with a "contains" method.
doesnt the unirdered set and map already have contains() and count()?
What you're talking about is called "sugared vs. desugared types". It would be on compiler implementers, not the language.
Btw the clangd language server already shows this in-line in IDEs (ShowAKA: True)
Is there something you need that unordered_map::count() can't accomplish?
I’d pay money for a compiler and especially a linker that can do that.
36:27 why does the 'deduced this' parameter refer to the overload object here, as opposed to the 2nd lambda?
Can you compose layouts? For example, say you want to stride columns, drop rows, and then rotate rows.
50:53 but now this accumulate template cannot be used with a BinaryOperation that just returns T rather than std::expected?
Wonderful. I've been programming C++ for over 25 years, and it's getting so complicated that even language experts struggle with concepts beyond C++17. Meanwhile, there still isn't standard library support for parsing UTF-8 strings, no standard network / GUI / actor library, no reflection, etc. I think the standards committee must pause adding esoteric features to the language for at least a decade or two, and look at what the industry is crying out for, and start focusing on libraries instead of extending language features. Some of the feature added during the last couple of decades have ended up being impractical (eg. futures), while ignoring better abstractions (like Actors). Perfect is the enemy of good enough ... However, I do understand the politics of committees, if you want to add you personal work/signature to the language/standard, your stand a greater chance of success by adding a minor language feature instead of adding a new library. Anyhow, good presentation Timur, we're lucky to have you as part of the community.
I am for once really happy there is no reflection.
C++ is probably the only “great” language that has managed to stay relevant without doing anything to reduce the learning curve or the developer experience. Move semantics ? Who is going to take care of letting the programmer know not use the old variable. Everything is brushed under the carpet of “undefined behavior”. Python-like ranges ? Let Erik Niebler write it first with ease, while producing some tangible benefit. The only great language not to have a network library. And lo and behold, it got a Boyer Moore search! More than half of the industry use C++ like C. I am talking about game devs here. The other half is hellbent on trying to make C++ look like Haskell. Embedded system programmers won’t touch C++. Linus Torvalds is welcoming to Rust instead of C++. The committee should pay some attention on these things.
I don't think adding things like GUI to the stdlib is a good idea. Those types of library that are opinionated and fast-moving are best kept as external dependencies with a few to choose from. In languages that have such things builtin the stdlib those APIs are often unused or deprecated. Part of the issue with C++ is that dependency managment is such a pain that everybody wants everything to be stuck into std
mdspan just ❤
Regarding if consteval:
It's not true that's only a cleanup because it allows you to do things you can't with if is_constant_evaluated like putting parameters in template parameters and basicly makes the function parameters constant ecpression.
Talk starts at 17:24
57:25: (n+1)-d arrays of numbers that are actually n-d arrays of structs is giving me terrifying flashbacks to Fortran and Matlab code that I have had to work with.
example with accumulate and expected is a bit contrived, at first we cannot change accumulate to add a stop condition, then we rewrite accumulate to handle std::expected. The generic way would be to add a stop condition as a parameter of accumulate, then it will handle std::expected case as well - and there wouldn't be no need for template metafunction to calculate return type - if you want std::expected as return value - pass an initial value wrapped in std::expected. Adding a stop condition to std::accumulate is a good idea in any case: sometimes further calculations cannot change resulting value anymore, it would be a good idea to shortcircuit in this case
In perl they always try to make the most used case easier to type (less characters), so instead of `print` and `println`; they have `print` and `say`.
If the optimal order for iterating depends on the layout (std::layout_left, std::layout_right, etc.), could we write a generator for index tuples that takes the layout into account?
for (const auto [i, j, k] : indices_for(matrix)) { /* ... */ }
Here, indices_for would be a library function that takes the matrix layout into account, and generates the indices in the most cache-friendly ordering.
If you can access the layout type from mdspan object, then probably yes.
Main part of talk starts at 17 minutes. Before that he tells us a great length who he is and what he is going to talk about.
You need a talk about features that are not explored in this talk.
I'd like to see deducing `this` taken even further: accepting smart pointers as `this`. There are contexts in which a member function of an object should consume the object itself, e.g. a task class that schedules itself in some thread-pool `void schedule(this std::unique_ptr, ThreadPool&)`, which would be invoked as `std::move(ptask)->schedule(pool)`. It also would allow for classes that behave like they inherit from `std::enable_shared_from_this` without actually inheriting from `std::enable_shared_from_this`.
OMG, this was the pain I worked on for approx. 1 month. But this needs a lot of language support.
Interestingly enough, the D language can do something like this. First, in D, there is no -> operator; since pointers have no members, D used ptr.member where C++ uses ptr->member. D has two things that could provide that: uniform function call syntax (UFCS) and opDispach.
1. UFCS is a language rule that effectively says: If x.f(args…) does not compile, try f(x, args…).
2. opDispatch is an “operator” that the compiler uses if it cannot find a member: If x.f(args…) does not compile, try x.opDispatch(args…) [note: this is not D syntax, but equivalent C++ syntax], i.e. it makes the supposed member’s name a template value argument; the function template can do whatever it wants with that information.
I’m quite sure, D could implement these - if it had smart pointers. I never used manual memory management in D because D has a garbage collector.
I ran into this issue myself. In Rust you can have a method take Self or Box to do this
Good thing we finally got a print function you guys. Too bad they didn't take the opportunity to provide a useful replacement for c-style varargs to do it. Or provide a way to use temporary memory for the allocations, etc. Instead, I'm sure it's just a template that has to be instantiated for every combination of parameters in the program. Maybe one day...
sad
pretty cool
Are we still going to have a header file and a library file concept? Isn't it possible to do away with these? Why can't c++ export functions and variables like the way other languages do? I can see some ppl creating header only code becaust of this eccentric problem.
Video starts at 17:19 Speaker wastes 17 minutes of your time talking about things he will not talk about in this video.
Sad to see executors are not there. They are very important
This was literally the only thing I wanted lel.
Вечная боль объяснять почему не используется юникод по умолчанию
1:18:50 I'm not laughing at the output, I'm laughing at programming in notepad! XD
It's so interesting to see the C++ crowd slowly approaching the features that other languages have had for years, but still act like somehow these are amazing new inventions
The Lisp community has felt this way for sixty years or so. I watched one of Herb's talks on his ideas on pattern matching and was thinking, "Just a little more and you'll have reinvented COND!"
This talk is an excellent primer on why you should port your C++ projects to Java, C#, or Rust. Or even just pure C.
Couldn't agree more. The slide at 36:45 alone is sufficient to convince me to program in Bash instead of C++
Note: The first 18 mins or is an account of features the talk won't cover.
Deducing this - по сути self аргумент из Раста, std::expected - по сути Result из Раста, std::print и std::println тоже есть в Расте. Может быть просто начать программировать на Расте? Тем более, что C++23 в реальных кодовых базах можно будет только лет через 5 использовать в лучшем случае, а Раст можно уже вчера.
Eh, Rust didn't invent those either, and it was never hard to return a tagged union.
@@ElPikacupacabra it was not the point, these things are already here in rust and you can use them today, not in 10 years
why naimg it "std::expected" instead of "std::result". expected is way harder to type ('e' and 'x', two adjacent fingers into opposite directions) and imho does not really convey the same meaning, even in the slides it was used for a variable named "result". It would also be in line with Rust, Kotlin, Swift, Elm, F# and the dotNext library for C#. (not that this would be an requirement, but why introduce multiple words for the same concept)
obviously this won't change anymore, but it's things like this where I can only shake my head in disbelieve.
I think this is the best advertisement of why not to use C++. Well done!
I love the whole presentation with one exception: at 1:00:32 I find that code extremely inefficient, for reasons I hope are obvious to most. And I'm not even talking about i+j+k that is just a ever-incrementing value from 0 to nz*ny*nx-1.
Moving on ...
I disagree completely that the new form of single template for the left right side thing is more elegant. No way in hell that clumsy syntax is elegant.
LOL STD::LAYOUT_RIGHT, as opposed to STD::layout_row_major
It makes a lot of sense after daft explanation based on a particular modality of thinking adopted by some rando’s odd-shaped meat-based processor. Now I have to perform this specific gymnastic each time I must reason with this ONE template.
mdspan supports more than 2 dimensions...
STILL no compile time reflection and codegen. I'm going to be dead before C++ becomes pleasant.
I'm not going to talk about this, I'm not going to talk about that... man just talk about the stuff and stop wasting time
Nobody std::expects the spanish inquisition.
Finally make package manager.
We can now this, we can now that, everything is awsome. Except there aren't even all the c++20 features in gcc or clang, let alone the c++23 features. I would love std:format. I don't know why they don't just copy and paste the fmt reference implementation into the standard library already.
The committee needs to go back to BASICS and KISS. This stuff is almost a solution for maybe 0.01% of problems.
I used recursive lambdas in the past with the self(self) workaround.
Or BASIC? :)
wow, 2023 and C++ is finally figuring out what functors are.
The video presents news from C++. All examples are syntactic. They only show syntax. Not many words are used for the semantics in them. When news is presented, the semantics in it should be presented clearly, otherwise it will just be talk for insiders.
This is a keynote. There’s an in-depth talk for each of the features presented.
Yeah, it doesn't offer any scenarios beyond trying to use the syntax.
it's time to start removing features to make c++ better instead of adding them.
Yeah, every two years, let's just change the way we write code. C++ is a mess.
I feel sorry for C++ developers, they really have trouble evolving, if this is their new way of writing code.
What actually bothers you? I am sure something bothers you, that's why you wrote below a video that talks about C++.
am C++ dev, I want to change language, someone help me switch career path
23 in "C++23" means how many years you need to learn all of this from the beginning. 😂
can ccp commitee enforce a rule of how many people can use &, this is so scary and how this can be mind f...??
Great, now generic code with deducible this looks like non-generic code. What a train-wreck C++ is now.
That's the entire point. Since C++20, simple template arguments can be expressed going from:
template
void function(V& value);
to this:
void function(auto& value);
Which is actually more elegant, easier to type, less painful on newbies... They've SIMPLIFIED the templating model and syntax here, and "deducing this" using that "auto" keyword syntax before it isn't just an arbitrary decision, it's based on auto as a new way to describe template type arguments.
Also what deducing "this" is allowing you to represent prettily is one of the most useful, but unfortunately ugly patterns of C++: the curiously recurring template pattern. It's used constantly for good compile-time polymorphic code, but the language had no good way of gracefully representing it until now... so 90% of programmers just abused "virtual" for functions instead.
I know most of this stuff is a matter of opinion, but I'm only saying this because it is my opinion that this is the single most important feature of C++23, and I'm not sure if you had the rest of the context. Most of the other stuff I couldn't give less of a crap about, but generics are becoming simpler and prettier, and now compile-time polymorphism isn't disgustingly ugly in C++.
std::expected
C++ these days really tries to be Rust 😂
Then Rust tries to be Go. Rust didnt invent these ideas.
it is monad
It tries to give you what Rust has.
Rust has evolved by borrowing from C++ too. Go study the history, you know nothing!
@@broken_abi6973 Go doesn't have enums/variants/results. Rust borrowed these ideas from ML and Haskell, not Go. Go borrowed its error handling style from C
(Copy-Paste my comment from other cppcon video)
I am starting to get nervous... Seems that to do c++ in the future, the source-code will be to pre-program the compiler to generate the code to be compiled by the compiler........... It is already this kind of programming right now in modern c++, and the std:: is surely becoming more and more undissociable to the c++ language itself !!!
The world is ending bros...
Thanks but not for me... I am returning to Borland C++ and TurboVision! ...In the land of raw pointers ; 🤣😁😎
I Cpp 😂
Everybody is driving me nuts with their structs in c++ code that should be classes. I'm think: "that shouldn't work. class inheritance is private by def... oh it's a struct again."
std::print, because printf is not cool enough. 😂
There are two types of programmers, good programmers and those who think modern C++ is the way to write code.
I know hope is dangerous, but I hope Mojo works out.
Those programming in C are lucky to not see their favourite language been messed up by fool who think they're improving it but they're destroying it. Making it way too messy and complex for new developer.
Exactly! I can't believe what is happening to this language D:
and they get to keep their habits while using the c++ compiler
backwards compatibility is pretty great for the one taking advantage of it
agreed. We were taught turbo/borland c++ in our school, which was just an OOP abstraction over c.
The modern language looks alien. it's way different than what we were taught. It's truly its own language which sometimes uses english, unlike the other languages which are built around English.
36:45 this is the highest amount of bullshit i've ever seen on a slide
hmmm talk about what you're NOT gonna talk about for 15+ minutes
Next time don't spend 17 min on things you don't plan to talk about 😅
hahahahahahahahahahahahahaaaaa too silly
c++ is hurling towards its own demise with all this complication. I dont think train can be stopped.
And sadly you can shorten that list even further as std::generator just shows how broken coroutines are - fixing a broken construct by adding more stuff.
And the stacktrace-library is borderline useless as the requirements are so vague that it can not be used reliably at all. The few examples i had seen and the few tests i wrote had only shown me that i'd be far better of creating and exception and catching it - that at least gave reliable information, where as stacktrace... yeah no. Several levels of the stack were just not there in the std::stacktrace.
Which makes these 2 far worse then not having them at all:
it is added broken baggage that is codified into the language. It has to be maintained by compilers, results in bad code, and it prevents the adoption of actually useful features. The broken coroutines alone have done more to convince people to switch to other language than anything else.
Why do you say that coroutines are broken?
This talk is impossible to follow as a blind person that has no way of knowing what's on the slides
Thank you for your comment! What can I do to make this talk (and future talks like it) more accessible?
What a mess this "deducing this" template pattern is.
C++ is trying too hard to not break up from old language model and it is hurting itself. Create some damn changes in the language and avoid the aberration that is trying to do everything in the std.
I'm filing it under "things I'll try to avoid because it's confusing, but I'm glad I know about it because one day I might recognise it when I've f__ked myself over with it".
You guys are insane. This is the single most important feature of all of C++23. Seriously. Look up the curiously recurring template pattern. It's incredibly useful, incredibly performant, and fuck-ugly. Good code uses it everywhere.
Now C++ can express this incredibly useful pattern concisely and consistently with the "auto" keyword being used in place of template syntax for generic arguments to functions.
I'm telling you. I get it, it's crazy looking. A lot of C++ is initially, but CRTP is a really important one for not abusing "virtual" every time you need polymorphism and incurring dynamic dispatch overhead. This particular one is actually worth learning and appreciating. The rest of the crap is whatever to me.
C++ is going nowhere..this is talking for purpose about talking..no real problems, no syntax improvments, no real libraries, no connection to real programming. This is sad, because of over 20 years of loving this language and what programming really is: solving problems, writing algoritms, sharing reusable code.
Uh, deducing this is a syntax improvement
Nobody talks about the dismal compilation speed with all this C++20 BS...
One of the ironies here is the perfection and optimization of technologies on the verge of obsolescence. A example is described in the classic book "The Mythical Man Month". The book relates how IBM developed the world's finest and most sophisticated overlay loader just when virtual memory made overlay loaders obsolete. Similarly code written by AI is rapidly making hand written code obsolete. A required extra parenthesis or lack of consistency is meaningless to AI coding. I really feel sorry for the brilliant C++ language developers who have spent countless hours on ultimately useless language improvements.
struct is NOT a CLASS, next use off this is translated inside the compiler as the parent pointer off the running process where you call the locall var function,..., self is same as this, C and C++ is not a framework or javascript, though it's poluted by casting and overloading by extern importn instructs that the compiler temperarily instructs to neglect. All defines in the headers , messing with that is not language defined but no knowledge off machine hierarchy is easy to hide in OOP, as objects are childs off parents, as an && against a var gives the adress off the adress of that var
catch that in a pointer * then you have the memory in controll, even when the locall stack releases you can move that in the globall stack.