CppCast - Better Code Concurrency

Episode Date: June 1, 2015

Rob and Jason are joined by Sean Parent to talk about his recent C++Now! talk where he presented a new futures library. Sean Parent is a principal scientist and software architect for Adobe’...s mobile digital imaging group. Sean has been at Adobe since 1993 when he joined as a senior engineer working on Photoshop and later managed Adobe’s Software Technology Lab. In 2009 Sean spent a year at Google working on Chrome OS before returning to Adobe. From 1988 through 1993 Sean worked at Apple, where he was part of the system software team that developed the technologies allowing Apple’s successful transition to PowerPC. News Android Studio introduces C++ support in v1.3 preview C++11 Port of Docopt, a command-line argument parser Going Native 38 Updates from Lenexa, future of C++17 Announcing C++Now 2016 and Best Session winners Sean Parent @seanparent Sean Parent's Github Links STLab Github C++ Seasoning Inheritance Is The Base Class of Evil Sponsors

Transcript
Discussion (0)
Starting point is 00:00:00 This episode of CppCast is sponsored by JetBrains, maker of excellent C++ developer tools. Listen in for a special discount code later this episode. And by CppCon, the annual week-long face-to-face gathering for the entire C++ community. Get your ticket now during early bird registration until June 10th. Episode 14 of CppCast with guest Sean Parent recorded June 1st, 2015. In this episode, we discuss C++ support in Android Studio. Then we'll interview Sean Parent and discuss his new Futures library.
Starting point is 00:00:52 Sean shares his thoughts in the direction of C++17 and tells us why we shouldn't be using raw loops. Welcome to episode 14 of CppCast, the only podcast for C++ developers by C++ developers. I'm your host, Rob Irving, joined by my co-host, Jason Turner. Jason, how are you doing today? I'm doing well, Rob. How are you doing? Doing good as always. You know, weather's a little rough out here, getting huge thunderstorms, so hopefully they don't interrupt the podcast too much, but otherwise doing good. Yeah, hopefully.
Starting point is 00:01:43 Yeah. So at the top of our episode, I'd like to read a piece of feedback. This week, I have some iTunes reviews. Dev War wrote in saying, this is a great thing for C++ developers out there. Great interviews with excellent content to improve your C++ knowledge. And I'm not sure how to pronounce this, but R-U-S-S-Z-A, I guess, Russia, says really well done, continue with great work. And they both gave us five stars.
Starting point is 00:02:11 So thank you both. And we love to hear your thoughts about the show. So you can always email us at feedback at cppcast.com. You can leave us reviews on iTunes or contact us over social media, twitter.com slash cppcast and facebook.com slash cppcast. So joining us today is Sean Parent.
Starting point is 00:02:31 Sean is a principal scientist and software architect for Adobe's Mobile Digital Imaging Group. Sean has been at Adobe since 1993, where he joined as a senior engineer working on Photoshop and later managed Adobe's software technology lab. In 2009, Sean spent a year at Google working on Chrome OS before returning to Adobe. And from 88 through 93, Sean worked at Apple, where he was part of the system software team that developed the technologies, allowing Apple's successful transition to PowerPC. How are you doing today, Sean? I'm doing pretty good. Glad to be here.
Starting point is 00:03:04 Yeah, it's great to have you on the show. So before we get to the interview, I had a couple news items to discuss. The first one is Google had its I.O. event this past week, and they announced that Android Studio would be getting C++ support in version 1.3, which should be coming out now. I think you can get it now in preview. Do you guys have a chance to take a look at this one? You have any thoughts on it? I did. I think it's long overdue. Yeah, yeah. I'm a mobile developer, so I've experienced Eclipse, and it's just a shame that they've been putting all this effort into Android Studio and haven't had any C++ support in it up until now.
Starting point is 00:03:48 But it's great to see it there now. And it looks like it's actually based on CLion because Android Studio, I guess, is letting JetBrains develop the IDE for them. So it should be pretty full-featured, having all the same C++ support you get out of the CLINE IDE, which is very nice. Yeah, that's pretty interesting. That should give them a good head start for C++ support. Yeah, absolutely. The next one is C++11 port of DocOpt, a command line argument parser. And this one was really interesting. It was based on a python project for parsing command line arguments
Starting point is 00:04:27 jason you have any thoughts on this one i am not familiar with the python version of this but looking no i'm not either looking at what he showed for the c++ it it looks incredible um i kind of wish i could put it to use as requirements. Say it requires at least GCC 4.9, which is a little bit newer than my minimum requirements, but it just looks amazing to be able to just give a textual description of what you want your command line arguments to be and have it do the right thing, if I'm understanding this correctly. Yeah, it looks like the whole thing is based on regex,
Starting point is 00:05:03 and that's why it won't work with GCC 4.8, because that version is missing the Regex module. Yeah. Sean, how about you? Did you have a chance to look at this? I did take a look at it. I thought it was interesting. I don't spend too much time writing command line tools these days.
Starting point is 00:05:20 Sure. But having more good command line tools out there would be nice it's always a pain when you run across those tools where you can't get help and the options don't parse well yeah definitely so just writing everything based on the usage output is definitely an interesting approach so it's definitely something I want to try out.
Starting point is 00:05:46 The next article is actually a video from Channel 9 MSDN, and it's Going Native 38 Updates from Lenexa. And basically, you know, apparently Microsoft sends about 60 or 70 engineers, I think they said in the video, down to the ISO C++ meetings, and they had two of the C++ developers report back. I think both of them are actually involved in some of the proposals. So just got their take on what went down at Lenexa. Sean, are you involved in the committee?
Starting point is 00:06:21 Not directly. I am on the mailing lists, and I get asked to chime in to some of the discussions from time to time I try not to attend the meetings though or get overly involved with it what do you think about
Starting point is 00:06:36 the direction of C++17 so far? I think it's going pretty well the three highlights that they're kind of pushing there, being module support is huge, especially for anybody who's doing large projects. And we certainly have a number of those here at Adobe.
Starting point is 00:06:58 So I think that's long overdue and a great thing to get into the language. Better support for concurrency is another one of the pillars they're looking at. And that's an area where I've had some involvement. And I certainly would like to see them do more there. And the last big piece is concepts, and that was something that was originally going to be in C++11 and didn't make it. We kind of restarted that with a Palo Alto meeting here a few years ago
Starting point is 00:07:40 and settled on a proposal for Concept Light, and that's coming along, and I think it's going to be a very nice addition and clean up a lot of the complaints that people have around templates and very long error messages. How confident do you think we are that Concepts will make it into C++17? I'm pretty confident that Concepts Light will make it into C++17. I think a few people have doubts and think that it might go through a TS first. I think that would be a shame. I think even a fairly minimal implementation of concepts light that just lets you have required clauses with basic predicates
Starting point is 00:08:32 on templated functions would go a very long way. So I would rather see them prune the proposals back a bit than push it off. Yeah, I agree. From the demos that we saw at C++ Now, it looked like it could really clean up a lot of template code. So it would be nice to see something available. Yes. And I think most of the arguments are people arguing that they want more. Right.
Starting point is 00:08:59 That's always the case. Can't have too much more, though. We really won't get it all in 17. Right. Well, Jason, I think you wanted to ask the first question to Sean. Sure. First, I wanted to congratulate you on getting best tutorial and most useful awards for your better code concurrency talk at C++ Now. I saw that was just posted on the website officially. Yeah, well, thank you. I was a little surprised that it was that well received, but
Starting point is 00:09:31 very glad it was. It was definitely an interesting talk, which brings me to my first question here is at that talk, you announced a new futures library and futures became part of the standard in C++11. So what did you see as the need for a new futures library? Well, the futures in C++11 are broken in a couple of ways. First is the behavior that they block on destruction when they're created by async, which is spinning up another thread. The other is there's no continuations on C++11 futures, so there's no.then clause where you can specify what to do next. That means that if you're running in a single-threaded environment, where I've been writing code lately,
Starting point is 00:10:26 running through the Emscriptum compiler to compile into JavaScript, that means that the current features are of no use. There's no way to get a value back out of them without blocking, other than using deferred execution, which is a whole other topic. So in a single-threaded environment, they don't do you any good. In the proposals for C++17 or the futures that will probably appear first in a TS, there are continuations, and there is an implementation of boost futures that have continuations. But the boost futures, again, as they're currently implemented at least,
Starting point is 00:11:20 not necessarily as they're currently defined, also aren't usable in a single-threaded environment. Continuations always go through the async mechanism. Although there is some facility there to let you define your own scheduler, that doesn't quite work as expected. So if you actually try to use.then and you don't have threading support, you basically just deadlock immediately. That does not sound useful. then, and you don't have threading support, you basically just deadlock immediately. That does not sound useful.
Starting point is 00:11:51 So that's what started me down the path of implementing my own. The more I got into it, the more I found that there were aspects of the current design that I don't like. One of those being using promises as the primitive for how you send information to a future. The problem there is what I would really like is that if you drop the last future, that it cancels the operation that feeds to it. But if your primitive is a promise, there's no good way to get information from the promise to say that all the futures have gone away. The communication channel is only one directional, not bidirectional. So my design with futures, my primitive is the function itself, the task itself,
Starting point is 00:12:52 which at first glance seems to be a little coarser, but it's actually not, because if you just have a package task that's a no-op, that effectively gives you a promise. So you can construct a promise easily enough with my futures, where with the existing design for promises and futures, you can't have cancelable package tasks. So that's the long story of how I ended up with my implementation. Okay. The main goal was to build something that would run on single-threaded systems
Starting point is 00:13:37 and supported cancellation and would scale well. So just to clarify, C++11 futures block on destruction. What do your futures do on destruction? So my future is on destruction will either just go away having no effect, but if the package task that they're associated with hasn't started yet, then the package task will not start. It just becomes a no-op. So in some sense the task that results in the future value is cancelled.
Starting point is 00:14:20 So if the task is already running, is it cancelled? Or does it just run and finish off on its own without you ever hearing about it? It just runs to completion and the result is dropped on the floor. Okay. Interesting. Is this library available now? Yeah, the library is available on GitHub in the STLab organization. There's a directory there called libraries. And I posted the code there.
Starting point is 00:14:54 Okay. And it's currently on the develop branch, is that right? Yes, it's currently on the develop branch. It might not be obvious if someone's looking for it. Yes. I should probably make the develop branch be the default branch for now. Yeah.
Starting point is 00:15:09 Have you started running this against different compilers? I haven't. Well, yes and no. I've run it against multiple versions of Clang. The development that I've been doing lately is iOS-based and and web based so i'm either going through apple's xcode version of clang or through m scriptum which is also clang
Starting point is 00:15:37 based compiler or through google's pinnacle tool chain which is also a Clang-based compiler. So it works in many versions of Clang. Clang is everywhere these days. It certainly is. Is the library seeing any production use yet, or do you think it's ready for production use? I think it's of production quality. I don't think it's quite complete. It could be a little more optimal in a couple of areas, but I am using it on a project I'm currently working on at Adobe, so
Starting point is 00:16:17 I will continue to keep it open source and feed in changes as my project progresses. So does Adobe, what is their policy for you creating open source that you're using inside their tools and whatever? Yeah, so it falls under the same guidelines that we have for publication policy, which is how you would go about publishing a paper. Open sourcing source code falls under the same rule set, which is basically you need your manager's approval. You need somebody at the director level to sign off and say
Starting point is 00:17:00 that it's okay. And if it's a large body of work, you're going to need an IP review just to make sure that you're not open sourcing something that's considered a trade secret or a patent or something of that nature. It is nice to hear that they have an actual
Starting point is 00:17:19 policy about it, though. I don't believe all organizations do yet. Yeah, that was something that when I was running our software technology lab that the software technology lab put into place and if you've heard of the Adobe Source Libraries that's where that started. We were actually Adobe's first open source project but Adobe now has a fairly large presence of open source projects up on GitHub.
Starting point is 00:17:49 And the Software Technology Lab, I've moved it just to the STLab organization that you'll find ASL there too, which is the Adobe Source Libraries. And right now it's mostly myself and a couple other people who are ex-members of Software Technology Lab that maintain that code and keep it going. Very cool. So what's the future of this library? Do you think it's something you might want to propose for the standard? It's not something that I would necessarily propose to the standard. I wanted to get it out there, though, and get the people who are working on futures for C++17, make them aware of it and raise some of the
Starting point is 00:18:40 issues. In putting it together, I had a few email conversations with Herb Sutter and a couple of other folks around where I saw the issues. And I know that there's a plan with C++17 that that futures should never block unless you call get or wait explicitly, but they should never block on destruction. Continuation shouldn't require blocking, should be able to execute in a single-threaded environment. So short of the cancellation model that I have there,
Starting point is 00:19:27 I think I'll get most of what I want out of C++17 futures as they're currently proposed. And maybe the committee will bend a little more and think about cancellation. With the coroutine proposal, I think we have a very nice cancellation model for coroutines. I unfortunately haven't looked at that yet, the coroutine proposals. But I do seem to recall during your talk at C++ Now, there was some contention about whether or not your cancellation model was something that everyone thought sounded like a good idea or not. I've seen people have a hard time wrapping their mind around it. Yeah, that frequently comes up. One reason is that people like to write continuations that have side effects and so some people want them to continue to execute even if you drop the future to them and if they're going to continue
Starting point is 00:20:34 to execute and have side effects then you get into this issue where people want better safety and so they would like you to block on the destruction. I think blocking is never the right answer. I think detaching and having, you know, being able to detach a task that's associated with the future and have it not cancel is certainly doable. I wouldn't want that to be the default. I mentioned in my talk that I think we should design with the idea that types are regular and functions are regular or pure,
Starting point is 00:21:23 and add support for the non-pure things as add-ons that complicate things and not go the other way around. So I could see adding a future dot detach method that would let you get the fire and forget behavior that some people want. I could see that. Yeah.
Starting point is 00:21:47 Yeah. So it would be an explicit detach. I just wanted to comment for our listeners here. I do highly recommend that you look at this code. It's only about 600 lines long. Your futures implementation, I believe, was 625 lines or something. Something like that. long, your futures implementation, I believe, was 625 lines or something. It's some of the most readable C++
Starting point is 00:22:07 I have seen, and I learned some things while I was reading it. So, I think it's educational for being succinct, readable, and also quite dense. It looks like you're using some C++14
Starting point is 00:22:23 library features, I believe. A couple of C++14 features in there. I do have a couple cases where I use deduced function return types, which is certainly a C++14-ism. It's not so C++14 heavy that I think the C++14 nest would be difficult to remove if somebody wanted to. I'd take a pull request if somebody wanted the library to support C++11 or get it running for Visual Studio or something like that. And the code as it is is a bit repetitive.
Starting point is 00:23:04 There's things that I would like to clean up there. At the last minute before I put it out, Eric Niebler convinced me that I should support move-only types so you could have a future to a move-only type. And so that added another template specialization. And so if you look at the code, there's a specialization for regular types, for move-only types, and for void.
Starting point is 00:23:36 And much of that code is redundant, so I think that that could be cleaned up and the implementation could be shortened quite a bit. I just haven't quite figured out the best way to do that yet. I personally have some code that has void and non-void specializations that I have not yet figured out how to clean up. So I will be
Starting point is 00:23:54 paying attention if you come up with some good ideas there. I want to end up this discussion for just a minute to bring you a word from our sponsor, JetBrains. C and C++ have a long history, going back to the early days of programming itself. Still, it's hard to find a good development tool for these languages. Luckily, our good friends at JetBrains, after spending over a decade making all sorts of tools for a great many technologies,
Starting point is 00:24:18 now provide C and C++ developers with three dedicated tools. CLion, ReSharper C++, and AppCode. All three take care of the routine and help developers focus on important tasks. They natively support C and C++, including C++11, LibC++, and Boost. C++ templates and macros are resolved correctly and supported throughout each tool.
Starting point is 00:24:42 Find your way through the code quickly with hierarchical views and instant navigation to a symbol's declaration. Boost your productivity by generating the missing members with override implement actions. Rely on code refactorings and be sure that your changes are applied safely throughout the whole code base.
Starting point is 00:24:57 Write better, safer, and more efficient code with on-the-fly code analysis protecting you from errors and redundancies before you even compile. Choose one of these three tools depending on your needs. For a cross-platform C++ IDE, choose CLion. If you work in Visual Studio, go through Sharper C++. Or if you develop for iOS and OSX, use AppCode. Visit jetbrains.com slash cppcast dash cpp to learn more and download your free evaluation or get a private license at a 25 discount using the coupon code cppcast jetbrains cpp tool and if you're a student or an open source project use all of them for free courtesy of jetbrains so you've given you know a
Starting point is 00:25:42 lot of talks over the years and several of them are available up on YouTube. Do you have any recommendations for listeners who want to see more of your stuff? What might be one of your favorite talks? Well, I think certainly my most popular talk is the C++ seasoning talk that I gave at Going Native. And in fact, when I gave that talk, kind of the sub-name for the talk became Goals for Better Code. And a lot of people asked me to write a book based on that talk.
Starting point is 00:26:20 And so my subsequent talks have been an excuse to flesh out chapters for uh for this book that may or may not ever get written but i'm trying to plow through it uh i think the one reason why that's a very popular talk is just the production quality at the going native conference was so high a number of talks that i've given are really difficult to watch online because the audio and video quality was just so poor. There's a follow-on talk to the C++ Seasoning Talk called Inheritance is the Base Class of Evil. And that's also been very popular. And that's somewhat interesting because I've given that talk with different titles but effectively the same talk
Starting point is 00:27:08 now many times over many years and I think it was just the title that made that talk popular and controversial. It is definitely a title that grabs your attention. Yes. So that's another good talk. Years ago I gave a talk at Google, a Google Tech Talk
Starting point is 00:27:38 called A Possible Future for Software Development or something along that line. And that talk has to do with a project that I've had ongoing on something called property models that I've now spent kind of over a decade working on these things. And I still think that that's a a good talk and and worth watching is that google one available online yeah the google one's available online okay now you got me curious about your property models that you've spent a decade working on yeah so is this a library or is it just a concept or uh there's a library to go with it um
Starting point is 00:28:30 in fact there's there's two separate libraries out there one is called the atom library which is part of the adobe source libraries and that's also on the st lab website. And there's another very different implementation of property models that's done in JavaScript, and that's the HotDrink library. That's also available up on GitHub, not in the STLab directory, but you can just search for HotDr drink on GitHub and you'll find it. And that implementation comes out of Texas A&M.
Starting point is 00:29:12 So I've had an ongoing collaboration with Professor Yako Yarve at Texas A&M, working on property models now for many years. Would you be interested in giving us a quick overview as to what property models are about? Yeah, so property models are very similar to a constraint system or to a reactive programming environment. In fact, I view them as kind of an extension of reactive programming. So if you're familiar with using a spreadsheet, something like Excel,
Starting point is 00:29:49 which is the canonical example of a reactive environment where you come along and you have cells that are value cells and cells that are equation cells, and the equation cells evaluate automatically when whatever they depend upon changes. So you change a value and all the equations update in response. Property models takes that basic idea but lets you group functions to represent relationships. So if I said that I had force equals mass times acceleration, given any two of those variables, I could solve the third variable.
Starting point is 00:30:34 And that's not something that's easily expressible in a spreadsheet. Right. But it is very easy to express something like that inside of a property model. And it turns out that any time you're implementing objects in a development environment, that the properties of your objects tend to be interrelated. In fact, when we talk about having invariance on a class, really what we're saying is that the properties of that class are somehow entangled. And it's quite common that changing one property updates another and vice versa.
Starting point is 00:31:21 And yet we code that as separate independent code paths when those independent code paths are really representing one relationship. So property models are a way to think about things like that differently and construct things by constructing what the actual relationships are and building the dependency graph out of that. And you find that if you actually go through and do the exercise, that there is a lot of things that you can prove about property models, and you can build model checkers that will make sure that for any set of values, you can get a result out of it. And they have a lot of nice, unique properties.
Starting point is 00:32:04 So that's something I've been working on for a long time. From a practical standpoint, where they get used the most is when you're trying to construct user interfaces. It turns out if you look at the event handling code that goes into most user interfaces, the user changes something in the UI and something else changes in response. And that very quickly in a complicated app just becomes this morass of spaghetti code when the user clicks here, update this, update that disable this, do these other things
Starting point is 00:32:36 but if the user clicks over there, go the other way with some different values and it's very error prone and it's a huge source of bugs in software. And if you describe these things with property models, a whole host of things, problems go away. Like you never have to say when a UI widget is enabled or disabled because that's a function of running a connected component algorithm on your dependency graph.
Starting point is 00:33:11 And so you can determine whether or not a widget is enabled or disabled. And so you can build a property model and attach a UI to it and your UI becomes self-functioning. I think you just laid out all the reasons why I don't enjoy GUI programming. There you go. I also just described my day job.
Starting point is 00:33:33 I'm gonna have to check that out. It sounds like that has to be interesting to you too, Rob. Yeah, definitely. Yeah, I would love to see what comes out of this property model work you've been doing. Sure. Sure. If you guys want to connect sometime, I'll give you a demo online. Okay. I'll keep that in mind for sure. So going back to some of your talks, I watched your Inheritance is the Root of All Evil talk today from Going Native.
Starting point is 00:34:05 And it's some pretty radical thoughts you put out there, basically talking about inheritance and polymorphism and how the way most C++ developers are using it really might not be the best way. Do you want to go into that a little bit? Sure, sure. Well, the point that I make in the talk as to why inheritance is evil boils down to many things. One is it's intrusive, which means that the derived class has the information about where the derived class is being used through inheritance. This tightly couples your software and makes it very difficult to reuse things.
Starting point is 00:34:55 You really want to separate those concerns and say, you know, an int is an integer not because it inherits from some integer base class but because it satisfies the requirements of being an integer and in Python you'll hear this referred to as duck typing which is if it looks like a duck and quacks like a duck it is a duck and quacks like a duck,
Starting point is 00:35:25 it is a duck. And this is basically the same thing. If an object models a concept, then it is that thing, regardless of whether or not you state it through inheritance. The other problem that comes into play with inheritance is it immediately pushes you into this space where now you have variable-sized objects. And as soon as you hit that, then people start newing their objects,
Starting point is 00:35:50 and now you've got a problem with memory management and with sharing objects. And one phrase you'll often hear me repeat in the hallways around here is that a shared pointer is as good as a global variable. And somehow, over the last few decades, we've come to the realization that writing code with a whole bunch of global variables is a bad thing. It makes it very hard to reason about a piece of code because there's no good way to reason about the code locally. You have to know what else is banging on those global variables.
Starting point is 00:36:27 Well, a shared pointer to a mutable object is exactly the same thing. When I'm reading a piece of code and I see a shared pointer in that code, in order to understand that piece of code, I have to understand every other piece of code that's banging on that shared pointer. So those were some of the reasons why I put in the talk that I think inheritance is fundamentally the wrong model for doing runtime polymorphism. And then the rest of the talk is showing how you can build in C++ a constrained version of dynamic typing. It's basically, you get dynamic typing,
Starting point is 00:37:11 but for something that models a particular concept. So I also call it concept-based polymorphism. And I think you can look up, there's a paper I published with a student from Texas A&M maybe a decade ago or so called Concept-Based Runtime Polymorphism. And it's much of the theory behind the talk, but just in paper form. So the idea is you can construct something that's similar to a boost any, but it can be an any drawable object or an any view object or an any event handler object or whatever kind of object you might need in your system. And you can have objects that model that but don't have to inherit from it
Starting point is 00:38:08 and can be used within that system. So you get polymorphism just exactly where and when you need it. And when you start writing code like that, you find you actually need far less polymorphism than you typically implement in an application. I think we tend to over design a bit. You make more functions virtual and stuff than you actually need them to be virtual, trying to provide
Starting point is 00:38:33 customization points. But if you can get it just on demand, you can always add an additional customization point later. And you don't have to bake it into your initial design. So it's a technique that I use a lot when
Starting point is 00:38:52 I write code. And I think it makes things a lot simpler. Have you kind of transformed the way they do software development at Adobe? Is everyone using your guidelines as opposed to using traditional inheritance and polymorphism? Oh, I certainly wouldn't say everybody does. I think I have a sphere of influence. So some people do. Adobe is not a monolithic culture.
Starting point is 00:39:21 Sure. We kind of have grown largely through acquisitions. We have lots of teams with lots of people with their own ideas. Uh, some people agree with me, some people disagree. So, but I'd say I've had an impact. So one of the things you mentioned in your C plus plus seasoning talk,
Starting point is 00:39:42 which, um, that I had never heard anyone talk about before, is you say no raw loops. And that one just kind of took me by surprise. I've been familiar with the standard library algorithms, but haven't put them to great use. But I just kind of wanted you to talk about that for a minute,
Starting point is 00:40:01 because what exactly do you mean by no raw loops? So what I mean is, unless the loop is very trivial and and if you watch the talk you'll see I define what trivial is but it's basically a simple for each or a simple transform where you basically have a one statement in the body for the for each or one statement in the body for a transform. If you have anything more complicated than that, then dropping a loop, you know, a for loop or a while loop or a do loop in the middle of some larger function makes it very difficult to reason about that larger function and to understand what that thing is doing, right? As soon as you hit that that while loop in a code review,
Starting point is 00:40:46 you have to start to think, okay, well, what are the loop invariants? Can I prove that this thing is going to terminate? What's getting affected inside of this loop that I'm later accessing outside the loop? What happens if this loop executes zero times? Okay? And run through all of that in your head while you're trying to read this piece of code. And it's very rare that somebody has a loop that's not implementing an existing algorithm. It's not a copy or a find or some form of a search. Maybe it's a lower bound.
Starting point is 00:41:27 I've even seen people hand roll their own sort in the middle of a function. Typically, by the time you get up to a level of sort, most people will agree, well, don't write your own sort. But yet people will often write their own copy. And it's much easier to just see the word copy and see the arguments to copy and you know immediately what that line of code is doing as opposed to if you see for and the body of it doing something
Starting point is 00:41:56 else. So when I do code reviews, and I do a fair number of code reviews, the first thing I always look for is just raw loops in the middle of functions and tell people, look, pull that out. And it doesn't mean you always have to replace it with a standard algorithm. Maybe you have a new algorithm there. But if you do have a new algorithm, write a good canonical form of that algorithm, whatever it is.
Starting point is 00:42:26 Right? Right? Spend a little time, do a little research, and package whatever that algorithm is into a library form. Maybe it's something out of Knuth, or a network algorithm book, or something like that. Give it a good name, and package it that way. So the idea is you want, you know, if something has a loop, you want it factored out into a separate algorithm and give it a name all to itself. And that just really cleans up your code when you're reading through it. It means
Starting point is 00:43:01 that all of the rest of your logic starts to just look like straight line code. And it's much easier to reason about. The example that you give in that talk, it looks like you went from pages of code to something that was like five lines long. See, clearly it's just three algorithm calls. Yes. Yes. And I think in general, people don't know the standard algorithms well enough to recognize them when they see them. Right? programmers out there and asked them what std rotate did or std stable partition did they probably couldn't do it and and so if you don't know what they are you're never going to recognize it when you're reading a piece of code and so part of the advice here of no raw loops gets people to actually read what their loops are and think about what they are and maybe spend a little time understanding what the tool set is that they have available to them and learning to recognize how to spot something when it's an existing solved problem.
Starting point is 00:44:29 So the example I actually gave in the book came out of Chromium OS, where effectively what somebody was writing was a rotate on a vector, but they didn't know std rotate, so they wrote it manually with insert and erase, which is a quadratic algorithm. And so not particularly beautiful and quite inefficient. And, you know, they just didn't know. Right. So take the time and learn. And there's a lot of useful building blocks in the standard algorithms i wouldn't say that it's a complete set there's certainly things
Starting point is 00:45:13 missing have a copy of of knuth on your shelf maybe a couple of other good algorithm books on your shelf and add some algorithms as you go well i, I have to admit my own, I guess, ignorance or lack of use here. I've read the documentation for all the standard algorithms at least once and still don't find myself putting them to use when I should. So I'm inspired to go through my own personal code bases and look for where I can clean those things up. Exactly. And you don't, you know, the way to learn to recognize them isn't
Starting point is 00:45:52 from reading the docs on what they are. It's from going through the exercise of figuring out what your own code does. Right. Right. Makes sense. Very good. Is there anything else you want to talk about before we let you go today, Sean? I didn't have anything else. Did you guys have any more questions? I think that's all I've got. Well, where can people find you online if they want to watch some of your talks or just find more information from you? So let's see.
Starting point is 00:46:26 I have a Twitter handle. I don't even know what it is. Certainly just Google for my name and you'll find lots of talks. I don't have a particularly common name, so that works fairly well. It's at Sean Parent.
Starting point is 00:46:44 Just all one word if you want to follow me on Twitter so that works as well I usually send out an announcement if I'm going to be speaking somewhere on through Twitter the only thing I have
Starting point is 00:47:00 upcoming planned is I submitted a talk for CppCon coming up in November. Oh, great. The two of us are both hoping to be there as well. Well, good. I look forward to seeing
Starting point is 00:47:16 both of you guys in person then. Could you tell us what your talk is going to be? Yeah, my talk if I do it is going to be about algorithms. It's another one in my better code series and the goal that goes along with this is no incidental algorithm or no i'm sorry did i say so the talk is on data structures and the goal is no incidental data structures
Starting point is 00:47:51 and what an incidental data structure is for anybody who's curious it's when you throw a bunch of pointers in your code so you have objects in your code that are interconnected but you have no explicit container that holds those objects. Okay, sounds like a really interesting talk.
Starting point is 00:48:13 Thank you so much for your time today, Sean. Well, thanks for having me on. Thank you very much. Thanks so much for listening as we chat about C++. I'd love to hear what you think of the podcast. Please let me know if we're discussing the stuff you're interested in or if you have a suggestion about C++. I'd love to hear what you think of the podcast. Please let me know if we're discussing the stuff you're interested in, or if you have a suggestion for a topic, I'd love to hear that also.
Starting point is 00:48:34 You can email all your thoughts to feedback at cppcast.com. I'd also appreciate if you can follow CppCast on Twitter, and like CppCast on Facebook. And of course, you can find all that info and the show notes on the podcast website at cppcast.com. Theme music for this episode is provided by podcastthemes.com.

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