CppCast - Deducing This

Episode Date: November 11, 2021

Rob and Jason are joined by Gašper Ažman. They first talk about some resources for learning C++ and learning how to work on the LLVM compiler. Then they talk to Gašper about the Deducing This featu...re coming to C++23, how the feature worked its way through the ISO committee and what it will change. News ADSP: The Podcast The Array Cast C++ By Example JetBrains CppCon Early Access CppCon 2021 trip report How to learn Compilers LLVM Edition Links p0847 Deducing This Defining Contracts Sponsors Use code JetBrainsForCppCast during checkout at JetBrains.com for a 25% discount

Transcript
Discussion (0)
Starting point is 00:00:00 Episode 325 of CppCast with guest Gaspar Ajman, recorded November 8th, 2021. This episode of CppCast is sponsored by JetBrains. JetBrains has a range of C++ IDEs to help you avoid the typical pitfalls and headaches that are often associated with coding in C++. Exclusively for CppCast, JetBrains is offering a 25% discount for purchasing or renewing a yearly individual license on the C++ tool of your choice, CLion, ReSharper C++, or AppCode. Use the coupon code JETBRAINS for CppCast during checkout at www.jetbrains.com. In this episode, we discuss some resources for learning C++ and compiler development. Then we talk to Gashper Ashman.
Starting point is 00:01:01 Gashper talks to us about introducing this feature coming to C++ developers. I'm your host, Rob Irving, joined by my special co-host, Connor Hoekstra. Connor, how are you doing today? I'm doing fantastic. How are you doing? Doing good. It's good to have you on here. Yeah, thanks for having me on. Yeah, it's been a while since we had you on as a guest. You've been on as a guest two times, I think.
Starting point is 00:01:51 And I believe since the last time we had you on, you have started your own podcasts, plural, right? Yes, that is correct. So I think probably most of the people that listened to my first podcast are going to be familiar with me from that one because it has, I think, quite a bit of overlap due to C++ as our main focus. So I started a podcast with Bryce Lelback, who I think you had on just a couple episodes ago. That podcast is called ADSP, which stands for Algorithms Plus Data Structures Equals Programs. And then there's a second podcast that focuses less on C++ and more on array languages like APL and J. That's with a panel of four different people. That's pretty cool.
Starting point is 00:02:33 I'm not familiar with what you mean by array programming languages. What does that mean? Well, very, very briefly, APL was a language created back in the 1960s by a guy named Ken Iverson. And it led to a very sort of niche community. It was big back in the 60s and 70s, but sort of died out. And its most popular sort of form of it exists in Python libraries like NumPy and Pandas. So those were largely inspired by array languages.
Starting point is 00:03:01 So the main thing about array languages is basically there's only one data structure and it's an array like multidimensional arrays. So there's no hash maps, no, you know, uh, you know, red, black trees or any of that stuff. Um, so yeah, I, I love it. Uh, if people are interested, they can go check it out, but, uh, I won't say more than that because that's, that's a whole other topic. Okay. Well, I'll make sure, uh, we get links in the show notes for this episode for, uh, for the podcast. Okay. Okay? Awesome. Cool. Well, at the top of every episode, I'll let you read a piece of feedback. Last week, we had Cy Brand on. We were talking mostly about Visual Studio 2022. We got a lot of comments on Reddit. I was going to quickly
Starting point is 00:03:39 read through two of these. One was, does IntelliSense work for modules yet, and how about for imported headers? I believe IntelliSense does work for modules in VS 2022, at least in the final release, which is coming out today as we're recording. I believe Cy did a demo of that
Starting point is 00:03:57 in their CPCon talk. Yeah. And the other question was someone was asking, is there any difference from the free community version instead of paying literally over $1, I think the criteria is like something like over five developers you're supposed to be paying for a license. But if you just want to try something out for yourself, definitely use the community version.
Starting point is 00:04:34 Yeah, I've used both in the past and they're both great. Yeah, I don't think you're missing out on a whole lot of features by just using community. I think the main thing is just that if you work for a company that you're supposed to be using
Starting point is 00:04:44 professional enterprise. Okay, well, we'd love to hear your thoughts about the show. You can always reach out to us on Facebook, Twitter, or email us at feedback at cppcast.com. And don't forget to leave us a review on iTunes or subscribe on YouTube. Joining us today is Gajpar Ajman. Gajpar is currently working on core libraries for research and trading systems. In the past, he's worked on large-scale distributed systems, such as the Amazon Retail Search Engine. He's a member of the British Standards Institute C++ delegation and has been a part of the C++ Committee since 2017. He's fixed some proofs in Stepanovs from mathematics to generic programming, published C++ The Beast is Back with John Kolb, spoken at C++ Now,
Starting point is 00:05:21 and is an author of Using Enum, which is a C++20 paper, deducing this, ordering customization points in C++20, and is currently working on contracts for C++26. He lives in the gothest part of London next to the magnificent Abney Park Cemetery and his friend DeCroze. Gosher, welcome to the show. Greetings. All right.
Starting point is 00:05:41 Yeah, that was honestly the longest bio that i've ever had i'm supposed to ask the uh the jason turner follow-up question about the bio but i'm actually going to ask uh something that's not in the bio that i just happen to know about you that i'm very very jealous of uh you're one of the few people that i know sort of uh in my age bracket that got to work with a Stepanov, correct? Yeah, I did. I worked with him for two years while I was in Dublin. I got to go to Palo Alto quite a bit and work with him. I was at the infamous Palo Alto meeting of the concepts proposal where you know sean parent came to visit alex and they talked
Starting point is 00:06:30 about how to you know structure concepts so it won't suck and uh we all know the history of that one um they they do not suck, mostly. We actually wrote quite a bit of pseudocode at that particular meeting. That was really fun. I mean, obviously, I was a super junior and did some of the grunt work of coming up with examples for the Grand Minds meeting
Starting point is 00:07:02 in the biggest meeting room of our Palo Alto office when I was at A9. But, you know, I got to learn a lot, which was great. And then after I actually moved to Palo Alto to be closer to the mothership, as it were, I actually, you know, like I spoke with him quite a bit, like I went up to his office his office you know a lot and he just talked about stuff he actually interviewed me for a night which was super fun i think it was a three-hour interview which started with uh me asking him what he thinks of ranges uh as as implemented in d and he muttered something i wouldn't report uh and and we ended at old church slavonic and how you dry
Starting point is 00:07:47 prosciutto like it was actually really really like all up all around cool interior it's probably the coolest interior i've ever had um yeah it was fun yeah i'm very very jealous of that opportunity it's not once in a lifetime but it's i don't think you know yeah steppenhoff isn't working anymore so it's something that yeah i would i would have loved to have the opportunity but very jealous of you thank you i'd be jealous of me honestly okay so uh gosh we got a couple news articles to discuss uh feel free to comment on any of these and we'll start talking more about the uh deducing this proposal and maybe some other work you've done. OK, so this first one is a new website, CPP by example dot com. And yeah, just a new resource for looking at examples of how to do various things in C++.
Starting point is 00:08:43 It seems to be pretty well put together. I looked at the about page and the author was saying how they're choosing to only cover the previous version of C++. So currently all the examples here are C++ 17 and they plan on adding C++ 20 examples once 23 gets published. Yeah, I took a look through some of the examples, and they're super nice and concise. I really like that. I really disagree with the ConstWest style, but I'll survive that one. The last thing that I think about this is something they really should fix
Starting point is 00:09:28 it suffers from the the problem if you've ever had a really large library of music like have the band start with the and so music programs have started ignoring that as a stop word in alphabetical sorts
Starting point is 00:09:44 and this one has a similar problem with how-to. How-to, yeah. They should really just ignore it in the alphabetical sorting of examples. But other than that, I think it's an excellent compilation of
Starting point is 00:09:58 just things that the newcomers to the language get stuck on. And it's an unsticker. I love it. It's a great project. That's funny. Yeah, I took a look as well. I agree, it's a great resource.
Starting point is 00:10:13 I wish it had included the C++20 stuff because there was a couple times, like specifically when they're talking about looking things up in containers, like there's the new contains method that it's very sad not to see that because it's like explicitly what a couple of times in the code examples is used for. And then another thing that stood out was the entry, how to add to an array. And I was like, oh, like that's not
Starting point is 00:10:36 possible because the std array is literally fixed size. But then immediately when you click on that, they say, oh, that's not possible. You have to choose a vector, which it's interesting that that's like they didn't make a mistake there, but they still left the title as it is, I guess, maybe array is known as non fixed size and other programming languages. But overall, it was, I think, pretty great. Honestly, I think that's a really, really great thing that they did. Because the way everyone will navigate this page is by control F. And at that point, the title has to have what control L will find. That's true. Okay, next thing we have mentioned Timur Dumler a few moments ago, I think this is his trip report for CppCon 2021. He has joined, I think rejoined,
Starting point is 00:11:28 JetBrains now as a developer advocate, and he was giving his perspective as an in-person conference attendee. I think I did a trip report, a registered report last week that was from one of the virtual attendees. Did either of you make it in person to CppCon this year? No, I couldn't have if I wanted to.
Starting point is 00:11:46 Timur has some very useful workarounds for being able to fly there this year from Europe. I did not attend either, neither virtually or in person. I heard great things about it. And also too, I'm not sure do we do either of you know what jet brains does because like previously uh they just used to release the talks on youtube but now now they're released uh through like a third party site with like private
Starting point is 00:12:17 links and uh i don't actually know so maybe jet brains can i'm sure there's someone from jet brains listening to this right now and they can tweet. Like, do they all get released at the same schedule and just through a different portal with private links? I didn't realize it was JetBrains releasing this. Are you talking about the CppCon 2021 videos? Yeah. So I think since maybe last year as well, like JetBrains has a new sponsorship deal somehow that for a certain period of time they don't get publicly listed it still all goes through the cpp con youtube channel but like that's how i consume all my online talks is just through youtube but now uh i think jet brains has some sort of mechanism where
Starting point is 00:12:56 they list them privately and get the links and then they do it through some portal but i can never i can never figure that out like uh so jet brains add us and let the community know how do we watch these talks um i mean i know the like the keynotes i believe have all been published and i saw links on reddit but you're right i'm looking at the cpv youtube page right now and i don't see any listings for 2021 but i know they're out there yeah exactly yeah i think the most recent one is from three months ago and is not a 2021 video. So,
Starting point is 00:13:26 uh, interesting. Okay. Yeah. We should definitely figure this out and, uh, let listeners know the best way to find the CP con content that's already up there.
Starting point is 00:13:35 And I'm sure the rest of the videos will be coming soon. Usually I think it takes a couple of weeks to get all of them out, but they get the keynotes right away. Yeah. Yeah. I was really hoping I could watch Ben Dean's talk on deducing this before this interview, honestly,
Starting point is 00:13:49 to like crib off his notes. If you're an avid talk watcher, and this is why I was so curious about the Jetbrain situation is I happen to know that Ben Dean gave a version of that talk at the North Denver C++ meetup. And if you know their YouTube channel, which is very small, it's only got like 86 subscribers,
Starting point is 00:14:07 there is actually a version of it online right now. We can link it in the show notes. So yeah, I'm not sure when that's coming out. He gave it at CppCon. I'm sure it'll be the same talk. But there is a version that exists online somewhere if you know where to look. Cool.
Starting point is 00:14:22 Okay, and then the last thing we have is a blog post about How to Learn Compilers LLVM Edition. And it's just a good collection of links for anyone who wants to get started in understanding how to get into compiler development. These are a bunch of shorter articles and videos that you could watch
Starting point is 00:14:44 instead of reading maybe a huge book depending on what your style of learning is. Seems like a good resource. I know this is not something I'm looking to do myself, get into compiler development. Either of you have any interest in this stuff? Yeah. It is a really surprisingly comprehensive, very short list for the really, really enormously broad topic that it covers. Like having written some compilers myself, although nothing as fancy as LLVM. Sure. It is pretty much the starting point for every
Starting point is 00:15:28 part of the compiler. You may have broken it down by front-end versus back-end, so if you're only interested in either of those, you could just focus on reading those resources. Yeah, but the mid-end is where all the complexity is. Sure, front-ends are complicated,
Starting point is 00:15:43 but usually they're well-specified. The midend is dark magic. I feel like we haven't really discussed the midend. What exactly happens in the midend? Well, the frontend gets you the initial intermediate representation,
Starting point is 00:16:00 right? Like, it takes the C++ or the Rust or the C or the Ada or whatever the hell human-readable mumbo-jumbo you have and turns it into something that university professors understand, which it in a symbolic representation is because all of this fancy research on the other end, which it from, you know, one way of representing the program to a much more streamlined and hopefully faster to execute way of representing the program. This is where you do loop unrolling and, you know, inlining and all of those fun transformations that eliminate a whole lot of work, such as not computing values that never get used, figuring out that you can transform a whole loop into a recursive equation that then gets executed in a finite number of steps. All of that stuff is done in the middle end
Starting point is 00:17:41 because all of these optimization passes work on the same language and then you give it to the back end thing that really like mostly just takes the intermediate representation if it's rich enough and an llvm it is rich enough and makes it into native code assembly and then there's a few people optimization passes to really find you and the outputs to whatever platform you're running on. But all of the really fancy stuff happens before that. Interesting. Thank you.
Starting point is 00:18:15 I can also second this is a great, super short comprehensive list. I mean, I've heard of probably half of this stuff and half of it haven't. In the general intro section, there's a free Alex Aiken course. He's a prophet Stanford on compilers that I worked through while I was at Amazon. And it's a great resource. And I haven't worked through this one personally, but the backend resource from NAND to Tetris
Starting point is 00:18:39 is a pretty well-known resource that I have a couple of friends that have gone through and they say it's fantastic because you basically go from like nothing to building up a Tetris game. So you end up with a really, really comprehensive. I mean, if you go through the whole thing and don't give up, you end up with a really comprehensive understanding of like every level, which is which is great. All right. So, Gashper, I know we've mentioned introducing this proposal before on the show. I don't think we've ever gone into it in any depth. And I don't know if you remember this, but I think like three years ago at CPPCon, when it was still being held in Seattle, Jason and I and yourself and a couple other attendees
Starting point is 00:19:16 and speakers, I think went to dinner. And I remember you speaking very passionately about deducing this. And it was kind of just like whoosh over my head so i was hoping you could maybe start off by giving like a high level explanation of what the deducing this proposal is oh i'll do you one better later on i'll i'll regale you with the story of um how before that dinner me and ben dean uh went to lunch and came up with the whole thing so that's when he started getting on okay interesting yeah yeah so so but to explain the proposal first and at this point i kind of want to stop calling it a proposal because it is a c++ 23 feature unless a national body objects at the last minute to actually passing
Starting point is 00:20:08 the standard, which won't happen because there's no actual serious objections to the feature. So yes, there is a procedural step still that could be invoked, but it won't. So in the end, member functions are
Starting point is 00:20:24 functions, and functions have parameters. And when you end, right, like member functions are functions and functions have parameters. And when you call a function, you supply arguments to match those parameters. And then the body of the function gets executed with the arguments, you know, having the names that have been matched. That's probably true of every function call ever. And for member functions, there is a parameter that behaves sort of weirdly, which is the object parameter. At
Starting point is 00:20:53 this point, up until this one, did C++ have this weird name this? That's why we call it the implicit object parameter. It is there whether you like it or not. If you don't like it, you need to mark the function static, and then it behaves totally differently, right? And when you have an expression like x.foo, then that x gets matched to the implicit object
Starting point is 00:21:19 parameter, becomes the object argument, and then the body of the member function gets executed. So deducing this is really just a way to say, to mark one of the parameters to the function, in this case, the first one, as the object parameter. So this is the one that you match the object argument to, instead of matching it to the implicit object argument that's it like and and in practice what this means is that instead of writing foo without arguments you say this my class name self as the first argument and that's it like that that function will now have a body where self refers to the x instead of this referring to the x. And you can't use this inside that function anymore for various reasons, which we can get into later if we want to. But yeah, that's really it. You designate one of the parameters to
Starting point is 00:22:22 the function as the object argument. And that's how matching happens for that function. Now, that seems like a pretty minor change, and it is, but it leads to a large number of places. Because since you now have a place to name the argument, you also have a place where you can write the type of that argument. Before the type was implicit because it was given by the class that the member function was contained in, right? But now we can write the type and we can be boring and write the same type and then put our ref next to it. And then, you you know everything happens the way it used to and it's all fine um we could write the qualifiers for the implicit object parameter before uh in
Starting point is 00:23:14 c++ 20 for instance you put them behind the parameter list for the member function right that's that's what the const ref after the parameter list looks like. That's really the qualifiers for the implicit object parameter, right? So now we can just write the qualifiers right there in situ where they belong realistically. That's why we can't write them redundantly at the end anymore if you have this parameter let's say um and because you can name the type if you make the member function a member function template you can now deduce the type using normal language rules um nothing surprising there but this turns out to be a huge, huge deal. For instance, if you are in a base class, if this is a member function of a base class, member function template, I should say,
Starting point is 00:24:13 and you are calling the member function on derived, the deduce type, just like for any other parameter, is going to be the derived one, which means we don't need the curiously recurrent template pattern anymore. This suddenly takes mixins from being a language feature that you need to understand templates to understand to anyone can write this, and it just works the way you'd expect.
Starting point is 00:24:38 You don't even need to write template anymore because since C++20, we have auto parameters, right? So if you just say this auto ref ref self, that's it. That's all you need to do. Self now behaves pretty much the way it would in Python. Hooray. It gets better because you can concept qualify that auto, right? Mm-hmm. Which means this member function only works for derived classes that also model this concept. And you can constrain your mixins that way. And it'll just work the way it's supposed to.
Starting point is 00:25:17 It does what you want it to do, basically. And it doesn't read weird, which is, I don't know, I just find it great. It's really useful for also every place that you needed to perfect forward the object parameter. Like the classic example for this is implementing, you know, the get method of optional or the star member function of optional, like the star operator, the reference operator, because you need to perfect forward
Starting point is 00:25:52 the return value qualifiers to the actual value that you contain. And this is actually a lot more common than people think. Every time you're forwarding a member function call to a data member of your class, you should be perfect forwarding the reference qualifier. Like, for instance, the vectors front and back should really be overload sets that had four different overloads. They're not, but they should be. Because if your vector is an R value, like going out of scope, why shouldn't you move out of the first parameter? Right out of scope why shouldn't you move out of the
Starting point is 00:26:25 first parameter right sorry why shouldn't you move out of the dot first um and the same should be true of any accessor to vector like if you're if your vector is an r value and you only need that one element please move out of it that should just be done if you're forwarding something um even if you have some kind of a callback which is another whole topic um and you're scheduling a part of that callback to happen again like you have a data member that needs to like you have some string that you need to log or something and you know you're not going to need anymore um you should be moving that string into your logger callback or whatever. But what if your callback doesn't know if it's going to be called again? Well, if it's being called as an R value, it's not going to be called again.
Starting point is 00:27:15 You can be pretty sure that it's going to go out of scope after the operator parents finishes. But if it's called as an L value, it very well could be called again. And in that case, you have to copy. That was actually the original motivation for this paper, because in lambdas, you cannot actually do that, right? Like in lambdas, you don't get qualifiers on your call operator, which means you cannot distinguish whether a lambda is being called as an L or as an R value. And I can get back to that later when we're at the store. So if you think about it, again, this gets us to recursive lambdas.
Starting point is 00:27:57 A lambda really is just the closure object with the function that you write in the code being the operator parens of that closure object. And really, that's how they're specified, that's how they're implemented, that's how they work. Which means that if you supply this auto ref ref self parameter to the lambda, you can now get at the closure object itself. Now, you still can't refer to members because they don't have defined names, and they might not even be there. That's a whole thing. But there are a few things that the lambda itself does support. For instance, calling it. Kind of obvious that you should be able to call a lambda. So you can call the lambda recursively. Another thing Lambda's support is moving them, right? Lambdas are movable. Some of them are copyable, or rather copy-constructible. They're not copy-assignable,
Starting point is 00:28:51 so they're not copyable. But they are copy and move-constructible, which means, let's say your Lambda's a callback. Your closure object is holding some resources that the callback needs. And let's say your callback gets called. It's currently being owned by the execution system that it's residing on. And it figures out that it actually needs to be called again. Either not all of your input has arrived yet and you need to be called again on the remainder, or maybe the timer has expired too early and you need to reschedule the timer to be called again once the event actually happens or whatever. Maybe your connection's not dropped yet.
Starting point is 00:29:33 Fine. Up until now, you couldn't make the decision of do I just return and not reschedule myself or do I reschedule myself from within the body of that lambda? Because the lifetime management of your callback system wouldn't be able to handle that. But now that you can get in the body of the lambda, you can just call schedule again,
Starting point is 00:30:00 move the closure object into the schedule call. So you move constructed object into the schedule call. So you move construct it again into the queue or whatever your schedule system is using and let the current closure always get cleaned up. Done. No more design space there. You can streamline a whole bunch of branches. It basically gives you the design space back
Starting point is 00:30:23 for the lifetime management. And this didn't used to be ergonomic so people didn't do it like they they had additional restrictions like you needed to return a boolean like yes i want to be cleaned up or no i do not want to be cleaned up or whatever from the from the call right um now there's no need to do that. Like my homegrown scheduler actually has a Y combinator built in because it didn't want to make people return a Boolean. So basically, when you write a lambda, you get your own object as the first parameter so that you can move, construct yourself into the next call if you want to. But people don't understand what a Y Combinator is, number one. So the ergonomics of that
Starting point is 00:31:12 are somewhat doubtful without inducing this. And it also takes a whole lot of template metaprogramming to do correctly. So I'd rather not do all of that. I love combinators, but yeah, the Y Combinator is I think Vittorio has a pretty good blog explaining it um but yeah not not my favorite combinator although it is a cute
Starting point is 00:31:32 trick to show the you know lambda and c++ using a y combinator but ideally there's a better solution and it's showing up in c++ 23 yeah exactly we don't need the Y combinator anymore. We haven't built into the language and it doesn't read like Y. Because Y is the appropriate response to seeing a Y combinator in code. There's another really, really cool consequence that only showed up
Starting point is 00:32:00 with coroutines. Coroutines of free functions work well enough. The one thing with coroutines is that you should really be taking all of their arguments by value because you need to ensure that they survive
Starting point is 00:32:16 until the coroutine exit. And if you're writing a generic coroutine, that means you can't rely on the environment ensuring that, which, you know, like leads to a lot more pitfalls for dangling things. And it's like super annoying. So taking things by value by default with coroutines, probably a thing you should do. Unfortunately, there used to be one one parameter in the language that you couldn't take by value. And that's the
Starting point is 00:32:41 implicit object parameter, like it's always a pointer. With deducing this, if you don't write the ref at the end of your type, it's not a reference. You take your object parameter by value, because that's what the language says happens. That's what it
Starting point is 00:32:59 looks like. That's what happens. Which means that you can now safely write coroutines as member function, and you're not going to leak your objects. Yeah, that's really nice. Right. It is really cool. And that is something we didn't foresee because coroutines weren't a thing when we were designing this. And it just so happens that it solves that, too, which, you know, is true of any good proposal. Like it integrates with the rest of the language
Starting point is 00:33:26 so seamlessly that you're like, why the hell wasn't this before? And, yeah, to sum all of that up, though, deducing this makes member functions as powerful as free functions, but keeps the nice syntax of member function calls.
Starting point is 00:33:41 And that's really it. There's no other weirdness. We just unified a bunch of the parts of the language and now they're no longer annoying to use. Want to wrap the discussion for just a moment to bring you a word from our sponsor.
Starting point is 00:33:57 CLion is a smart cross-platform IDE for C and C++ by JetBrains. It understands all the tricky parts of modern C++ and integrates with essential tools from the C++ ecosystem likeBrains. It understands all the tricky parts of modern C++ and integrates with essential tools from the C++ ecosystem, like CMake, Clang tools, unit testing frameworks, sanitizers, profilers, Doxygen, and many others.
Starting point is 00:34:14 CLion runs its code analysis to detect unused and unreachable code, dangling pointers, missing typecasts, no matching function overloads, and many other issues. They're detected instantly as you type and can be fixed with a touch of a button while the IDE correctly handles the changes throughout the project. No matter what you're involved in, embedded development, CUDA, or Qt, you'll find specialized support for it. You can run debug your apps locally, remotely,
Starting point is 00:34:38 or on a microcontroller, as well as benefit from the Collaborative Development Service. Download the trial version and learn more at jb.gg slash cppcast dash cline. Use the coupon code jetbrains for cppcast during checkout for a 25% discount off the price of a yearly individual license. Sounds awesome. Do you want to talk some more about the original inspiration when you started working on introducing this right right yeah so uh it was cpp con 2017 and uh i was young and you know happy um and i was at cpp con i was meeting all of the cool people and I had met Bandin a few years before and
Starting point is 00:35:28 we caught up in the hallway after I think it was Alexandrescu's keynote or something something like that we were in the hallway, we wanted to go to lunch and he said, you know what's really bothering me
Starting point is 00:35:44 these days? i can't know from a lambda whether i'm being called for the last time because i'm returning a bunch of things and i want to know if i can return them by move or do i have to return by value which would copy and it's inefficient and i just like it really grinds my gears. Ben is like that. He wants everything to be perfect. And I said, you know, if you could figure out the qualification of the lambda function call, then you'd be able to do that
Starting point is 00:36:16 because you'd just be called as an R value. It really is the R valueness of the closure object, isn't it? That's really what we're- What if you were able to just get- What if you were able to name your closure object? I remember having this epiphany when I walked right through the door of the Maiden Bower Center, where CppCon used to be. And that's when it clicked.
Starting point is 00:36:43 Like, yeah, of course, you should just be able to name your this parameter and know the qualifiers on it. And then we sort of hashed out the syntax at lunch. And it wasn't the current syntax was worse. And then we had a few more dinners with some other people. And yeah, that's how we arrived at, we should write a paper. So we did. And then we shopped it around. And
Starting point is 00:37:15 I, for the life of me, couldn't find who said, you know what? Barry and Cy Brand are writing pretty much the same paper. And I said, they are? Let's get in touch. So I get in touch with Barry over Twitter. As we all know, all committee business is done on Twitter.
Starting point is 00:37:35 And it turns out they started from a completely different place. They didn't start with the value category of lambdas and recursive lambdas. They started with optional. And how annoying it is to have to write four overloads of freaking every member function of optional, especially since Cy was already working on monadic optional and dot then and all of those maps and things like that need all the forward in order to be correct.
Starting point is 00:38:01 And so it was just a mess, right? And not only was it a mess, it compiled slower because you needed to forward to another free function that implemented your logic so that you could prove it and then just do the casts. And if you use std forward, that's more function instantiations and it's horrible at debug time because you have to jump, like in a debugger, you have to jump through all of the std forward which is amazing. And so on.
Starting point is 00:38:35 So Cy was really pissed about optional and I was really pissed off about lambdas because all the committee proposals start because somebody's pissed off about something. We're a very angry bunch of people uh and that that that's why we do a whole bunch of work um over years the anger does not subside until the work is done um yeah so so anyway they had a different syntax in mind because they started from a different place.
Starting point is 00:39:07 And so it ended up that we went with the syntax that me and Ben were proposing in our paper. We ended up using their paper number. And then there was the whole saga of how do we get this through the committee? So when we first merged the papers uh barry was planning to present it at ewg and we uh shopped it around a bit and there was a lot of resistance what committee meeting was this at do you remember oh god no you know what year it was well it would have been 2018 but i think it happened after my C++ Now talk because once we wrote the paper, we realized
Starting point is 00:39:52 that there was a lot of resistance and we didn't even present it. It was just like, oh, this is new novel syntax and people are like, why are you doing this? This seems like it's not useful or something. I said, okay, wait until C++ now. Let me present this. Let me actually have like a proper hour, like, what was it? Three hours? No, it was an hour and a half that went over by like half an hour. And the C++ Now crowd loves to hackle, which is great because you iron out all of the problems with proposals. And so we had this extended presentation at C++ Now where I not only presented the paper, but like four different
Starting point is 00:40:34 extensions that we're planning and why the syntax needs to be the way that it is, and so on and so on and so on. And we ironed out quite a few problems and we were able to actually listen to people's issues with it throughout the week of C++ Now. It ended up being a really great time to iron out things and also to socialize the proposal. And the reason you need to socialize
Starting point is 00:41:02 novel syntax, I find, is because committee people are still people and human brains do not like change and we're always like oh then there's another thing i have to learn why why are you doing this to me i don't need it um but it turns out that when you present something and then three months later a person sees the same thing recognition turns out to be a really positive emotion and so people when they saw it again were like oh yeah i've seen this i understand this and it's a it's a neat feature i kind of like this and so this i kind of like this went in several waves throughout the committee. And it's really funny how every single person seeing this paper comes up with the same objections at first.
Starting point is 00:41:50 And when you explain to them what the problem is with the alternative proposition that they're making, they're like, oh, but this. And it's one out of the two predictable things. And then you just work through the graph to the same place where we ended up um and the funniest thing is that's where we start like the paper authors that's literally where we started so when this was first presented at ewg they did not like it um so we presented it again with you know having done more research like the committee is always happy
Starting point is 00:42:25 to approve more work right um so we did more work we presented it again there were four syntaxes in that second iteration and the committee the ewg had a poll about which one they liked the most after the presentation and predictably picked the wrong ones. And so then all of us four authors went, oh my God, why? Okay, we're now working on a paper where we don't like where it's going. This is not what we signed up for, but let's just write it.
Starting point is 00:42:57 Like it's better than nothing. Fine, like EWG wants it that way. Let's do it that way. And we did it that way and it was like wrong. It was so wrong that we were like, no, we need to somehow reverse this. Fast forward to CppCon the next... That was now
Starting point is 00:43:11 2018 CppCon, I think. The start of this went pretty quickly, I think. And I get a stop herb starter in the hallway. He is the committee convener for anyone who doesn't know. Also really an amazing mind.
Starting point is 00:43:32 And I explain to him the issues, and he predictably comes back with the same graph of things that I've already talked about. And we walk through the graph in an hour and a half, which, to his credit, that's incredibly quick to get through all of the phases of deducing this design. And he says, yes, I see. EWG really did make a mistake.
Starting point is 00:43:54 I believe that this can be reversed. Why don't you talk to Ville, who used to be the chair of EWG at the time, and figure this out? So I take Ville to lunch. Fortunately, the CPP gone. Everybody's there and it's not a committee meeting, so everybody has time, which is great. So, over eating a sandwich, I explain to
Starting point is 00:44:15 Ville what happened and ask him what we can do about this because this is going the wrong way. And we have polls from EWG and he said, ah, Gaspard, don't worry, this is material new information. Write that into your paper. Present the syntax as you want it to be, and I'll schedule it. It's good.
Starting point is 00:44:35 So we get rescheduled with material new information, which basically was just, y'all are wrong, please reconsider. And they did. So after that, we were basically clear on DWG, but because the paper had changed so many times, everybody was super scared about passing something that wasn't properly vetted and didn't have an implementation. And there were issues that turned out not to be substantiated
Starting point is 00:45:02 over the implementability of the recursive lambda part. There used to be a recursive lambda proposal that was an alternative to this one. Turns out it wasn't implementable for various reasons, but the main one is in the other recursive lambda proposal, which gave the lambda object a name outside of the parameter list, you couldn't do size of the closure inside the lambda body because that turned out to not be computable without solving the halting problem. Turns out with deducing this, you can't actually name the type of the lambda inside the parameter list
Starting point is 00:45:45 because it always has to be a template. But the other proposal could be a normal function. So with deducing this, it always has to be a function template because the lambda body isn't formed. There's no way to get decltype of it at that point, right? So there's literally no syntax you can use to divine the type of the lambda,
Starting point is 00:46:03 which means the size of expression is dependent and everything magically works. So it took me another few months to CPP now the next year to sit down with David van der Woerde and explain to him how that works. And then at that point, he had
Starting point is 00:46:19 enough information to say, yes, I believe this is implementable. And then Barry sat down with him a few months later and implemented it in EDG, the EDG compiler. And so when the implementability of Lambda issues solved, we got seen by EWG again, and
Starting point is 00:46:35 they approved it, but said, you know what, we're still uneasy about this, and then we got seen by EWG again the next meeting saying, we have nothing more to say really like nothing happened in these three months we did some more research it all works we've got wording um so should should we just send this to core and ewg sent it to core and yeah that a few votes later here we are in c++ 23 it's it was a saga yeah it's interesting because i
Starting point is 00:47:06 primarily sit in a library uh and so i i don't often sit in language even though it's all virtual now so it's whatever just sitting in your own apartment um but my view and this might be biased because i speak to ben quite a bit is that there was like uh you know the deducing this paper at least towards the end had like pretty good consensus. And like, it was one of the least controversial because of how well it played with all the other, like it's,
Starting point is 00:47:32 it's very rare to have a new language, like something on the language side that just works with almost all the other existing language things. And because of that, there wasn't too much, you know, controversy about this getting in, but it sounds like that is not the way it started. existing language things um and because of that there wasn't too much uh you know controversy about this getting in but it sounds like that is not the way it started um that it was a long
Starting point is 00:47:51 uphill battle um for for what ended up being or i don't know is it still controversial at this point or no i'm not even mistaken okay yeah so it it got consensus but it took years. It got years for people to get familiar and comfortable with the original design, basically. Interesting. Which is not how most paper goes. Like most papers go through a lot of iterations where there's tweaking and so on. This paper pretty much got born and then elaborated until all the FUD was gone. FUD being fear, uncertainty, and doubt for people who are... So what are the top things developers should know when C++23 comes?
Starting point is 00:48:33 How will deducing this make their lives simpler? Is it the CRTP pattern is just going to go away and you can write that type of code a lot simpler? What kind of things should we highlight? I think that it really depends on what kind of code you're writing okay like for me the code that i write like 20 of my code base is just gone uh because it's mostly forwarding through various layers and like simple program transformations that have so much forwarding and forwarding and forwarding and forwarding. I did a quick survey before the show,
Starting point is 00:49:09 and actually half of my function calls are going to be gone because I don't have to forward through an additional layer anymore, even. So it'll compile way faster. There's no more overload resolution between four alternatives anymore, so it'll also compile way faster. There's no more overload resolution between four alternatives anymore, so it'll also compile way faster. And also not having to write that is a huge win. Yeah, it's a huge
Starting point is 00:49:34 win, but I write domain-specific languages. I write libraries that connect various components together. Specifically this year, I've been writing lock-free schedulers. And that's all about shaving off every cycle you can through inlining. And it turns out that forwarding
Starting point is 00:49:54 is a really good way to inline things because the compiler sees that, yep, this expression really is type identical to that other one. And it has the same pointer, done, right? That's not true for a lot of my colleagues who don't write function templates all that often. And for them, not a whole lot is going to change. For people who write a lot of type
Starting point is 00:50:16 erasure, things get really interesting because of by-value parameters because you suddenly don't have to erase four overloads. You erase the by-value one and expect the language to move. And that allows erasing factories that basically wasn't ergonomically possible before. And that's why nobody did it. There's a whole lot of things you could do in configuration that you couldn't before,
Starting point is 00:50:41 just because the code ended up being so horrible. But yeah, other like giant code reductions it doesn't enable a whole lot of things um but because it makes so many things that we used to do a lot easier i think that uh there's going to be a lot of emerging patterns built on top of this that we just didn't like some of us did them in spite of the language because we had to but i think a lot of these advanced quote-unquote patterns that we used to uh leave to the library authors where speed was important we will just expect normal uh everyday programmers to just use because they're now nice. They're no longer horrible hacks, effectively. So I think that it'll streamline that,
Starting point is 00:51:29 but it won't change. I mean, it might change the paradigm down the line when people adopt the new idioms, but who knows? Idioms are always emergent. For folks that are interested, too, on top of Ben Dean's talk that'll be on CppCon and that's on the other YouTube channel, the paper itself is littered with like before and after Tony tables or whatever we call them.
Starting point is 00:51:52 So if they're curious of what the difference is, like a ton of it is like, you know, it's it's like a fraction. The after table is a fraction of what it is on the left. Yeah, it looks it looks awesome. Very cool. We're running a little bit low on time, but I did want to quickly ask you, you're also one of the authors on defining contracts. And I wanted to ask kind of how is that paper progressing? Do we think we're going to be getting contracts back in the language after it was dropped from C++20? Right. So defining contract is not going to progress anywhere
Starting point is 00:52:25 because it's a let's agree on definitions paper so it's a it's an fyi and not a design okay um but i'm also a co-authored on the closure based syntax for contracts proposal i'm also the co-author on the mvp for contracts proposal So those are probably better ones to cite. The numbers are P2463 and P2388. So what happened there is that contracts were not baked for C++20 and we took them out. And ever since, we've sort of been figuring out in the contract study group what the minimum viable product looks like, because we don't want to ship everything that anyone could possibly want in the P0. We think that we have agreement on what semantic features
Starting point is 00:53:26 need to be there, but it turns out that a lot of people dislike the attribute-based syntax that the original C++20 proposal used. And that's for various reasons, not least because it looks like attributes.
Starting point is 00:53:43 Contracts are this really surprise pedantic design space because we also put them into places that are shared with C, that is headers. And so we actually need not to design just for C++. We need to design something that C is going to want to use in roughly the same fashion as well if we can. And with C, it turns out that where the contract proposal currently puts those things is in the attribute space that applies to the function type and not to the function definition. And contracts don't really apply to the function type. They apply to the function that you're defining.
Starting point is 00:54:25 And so they're in the wrong place if they're an attribute. There are worries that that will cause confusion. I have other worries about that syntax, and it's just very constrained for what else we want it to do. For instance, there's no nice way to really express a closure in that syntax. And fundamentally, a contract checked in a post condition is a closure. You construct the closure at function entry, and you run the predicate at function exit. And if you think about it that way, a whole lot of things just get answered for you. So at that point like if you know it's a closure why don't just write it like a closure like a lambda basically that has to return boolean so you can emit the return just like requires expressions do um the return value has to go somewhere oh Oh, wait, we've got this thing called function arguments.
Starting point is 00:55:26 We can put the return expression like the return value through there, but we don't need to specify its type because auto ref ref is what you always want for that one. So we're kind of driven towards the syntax for
Starting point is 00:55:42 abbreviated lambdas that Barry Revzin proposed a while ago and got rejected by EWG for lack of useful applications of the syntax. Turns out we now have a useful application for that syntax. And I hope that we get somewhere with that. Unfortunately, the contract study group, for good reason, is not exactly thrilled about waiting for EWG to mull over abbreviated lambdas before we pass contracts.
Starting point is 00:56:14 So we have problems, basically. Fortunately, with regards to C, C is actually passing lambdas very soon, I believe. They don't have closures, but they are inner functions that you can just pass to Qsort or whatever they have, right? And they use roughly the same syntax as in C++ because somebody looked at it and said, this seems good. So if we pass something that looks like lambdas,
Starting point is 00:56:42 C might very well adopt it as well. And that means that C and C++ can share contracts and headers. And that would be wonderful. That sounds great. But yeah, that's kind of what we're hoping to achieve there. It is not going to make C++ 23. I was going to say, it sounds like the soonest that's going to show up is C++ 26. And honestly, abbreviated lambdas coming because of contracts, that's
Starting point is 00:57:05 news to me. I know you don't want to wait for it, but I would absolutely love Barry's paper to be able to be brought back to life and go through. That's like a selling point of contracts for me now. Yeah, well,
Starting point is 00:57:20 speak up. I think people need some cajoling. All right. Well, G up. I think people need some cajoling. All right. Well, Gashper, it's been great having you on the show today. Thank you so much for telling us about reducing this. Well, this has been a pleasure. Thanks for coming on. Yeah.
Starting point is 00:57:35 See you some other day. Thanks so much for listening in as we chat about C++. We'd love to hear what you think of the podcast. Please let us know if we're discussing the stuff you're interested in, or if you have a suggestion for a topic, we'd love to hear what you think of the podcast. Please let us know if we're discussing the stuff you're interested in, or if you have a suggestion for a topic, we'd love to hear about that too. You can email all your thoughts to feedback at cppcast.com. We'd also appreciate if you can like CppCast on Facebook and follow CppCast on Twitter. You can also follow me at Rob W. Irving and Jason at Lefticus on Twitter.
Starting point is 00:58:02 We'd also like to thank all our patrons who help support the show through Patreon. If you'd like to support us on Patreon, you can do so at patreon.com slash cppcast. 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 was provided by podcastthemes.com.

There aren't comments yet for this episode. Click on any sentence in the transcript to leave a comment.