CppCon 2018: Bjarne Stroustrup “Concepts: The Future of Generic Programming (the future is here)”

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Oh god.... The cppcon binge watching begins....

👍︎︎ 76 👤︎︎ u/PoopIsTheShit 📅︎︎ Sep 25 2018 🗫︎ replies

Already up the next day.. awesome!

👍︎︎ 29 👤︎︎ u/_SunBrah_ 📅︎︎ Sep 25 2018 🗫︎ replies

Worth pointing out, because this will surely be a common mistake with CTAD. At 18:02:

vector v{begin(c), end(c)};

Gives you a vector holding two iterators to c, it does not call the iterator pair constructor. What you need to do is:

vector v(begin(c), end(c));

Also vector{c} is not a thing. There is no constructor for vector that takes an arbitrary range.

👍︎︎ 28 👤︎︎ u/sphere991 📅︎︎ Sep 25 2018 🗫︎ replies

Wow, that was fast! I wasn't expecting to be able to watch these for a couple of weeks.

👍︎︎ 21 👤︎︎ u/Theninjapirate 📅︎︎ Sep 25 2018 🗫︎ replies

I'm still skeptical about the lack of definition checking, but I guess time will tell.

👍︎︎ 18 👤︎︎ u/0b_0101_001_1010 📅︎︎ Sep 25 2018 🗫︎ replies

On slide 26 (~29:32) he uses input_channel as type.

Is input_channel a concept? is it a "narrow" auto?

👍︎︎ 3 👤︎︎ u/ManicQin 📅︎︎ Sep 25 2018 🗫︎ replies

anyone know where the clang implementation of concepts is right now?

I saw a post a while ago about there being an experimental branch on godbolt, but haven't seen much about it since - and clang 7 just shipped without it, from what I can tell.

👍︎︎ 3 👤︎︎ u/Xaxxon 📅︎︎ Sep 25 2018 🗫︎ replies

Presentation Slides, PDFs, Source Code and other presenter materials are available at:

https://github.com/CppCon/CppCon2018

Edit:

They are not uploaded yet, but I assume they will be uploaded under this repository. Copied the link from the youtube description.

I would appreciate if someone who found the slides could post a link here. I can't watch the video at work

👍︎︎ 3 👤︎︎ u/zzzthelastuser 📅︎︎ Sep 26 2018 🗫︎ replies

Is the (Concept auto val) syntax really the way we’re heading? It’s awfully redundant.

👍︎︎ 6 👤︎︎ u/mechacrash 📅︎︎ Sep 25 2018 🗫︎ replies
Captions
♪ I'm with the big shot, yeah ♪ ♪ Yeah, yeah ♪ (lively music) (attendees applauding) - Bjarne Stroustrup has been a guiding force for this community and has done a lot of work to promote C++ and to build a community out of that and so I wanna, I'm looking forward to his talk today where he's gonna tell us a little bit about concepts and what that means. Thank you very much, Bjarne. (attendees applauding) - Thank you very much. Okay, wow. If I could see all of you, I'll be intimidated but fortunately, thanks to the lights, I can see about two lines here. So I'm going to tell you a little bit about concepts and in some ways, that's a very old topic and others thinks it's new. You can start using it. Some of us has been using it for years. It's getting into production in places. So I'm going to talk a little bit about generic programming then I'm going to say what do we actually get out of concepts and what are concepts and how do you build useful ones. So, basically, you can go back to the early aims of David Musser and Alex Stepanov. Basically, wanting to get generic programming in as a discipline, providing more flexible, better code with a focus on, on algorithms as opposed to data types. And my aim is sort of fairly simply stated, making generic code as simple as non-generic code. This is one of these modest and ambitious aims that can drive development, so I'm going to do that. Obviously, when you have generic code, not all code can be as simple as if you're just writing code based on knowing that everything is a double C. So, more advanced generic code should be not unnecessarily complicated but it can't quite be as simple as non-generic code. And one thing I would like to emphasize and I feel I probably won't be able to do it as much as I would like to is it's not just for foundation libraries. There's a lot of application code that is generic and you shouldn't just think about it as something, oh, a standard library that you don't really need to think about. I was talking to a bunch of theoretical physicists a couple of weeks ago. It's there in their stuff that's certainly not foundation library. I talk to generic, embedded systems programmers that use it for certain aspects of device controls. This stuff, concepts is not just a hysteric, it's not academic at all and it is not just for foundation libraries. Basically, the whole game is to write a better code and better code has all the usual requirements here. Nothing has much to do with generic programming but the point is that if you write generic program in good generic code, it helps with all of those things. And it's basically a significant help. I really don't like talking much about individual language features. A language feature and isolation is usually boring and you can talk about where you put your commas and semicolons and some people like that, I don't. I tend to fall asleep over that. It's necessary at some level but I'm trying to get the big picture. So this is not a talk about language technical details. if you want to know the latest about the debates in the Standards Committee, well, go to one of the other talks to the other committee panel or something like that. This is not what I'm trying to talk about and there are at least four talks at this conference that goes into details about generic programming and concepts so that's another good reason for me not to go into those details. So the concepts have been moving through the standards process, too slowly, in my opinion of course but I'm known to be impatient. And basically, the TS was approved two years ago and we have the explicit requires clauses in the working paper now. Barring utter disaster, it will be in C++20. We have the shorthand notation so that you can instead of just saying I want the type N, I can say I want here a random-access iterator and we have requires expressions to express things directly in the language. Not quite yet. We hope to get ranges into the working paper in San Diego. That's less than two months away and again, that seems to ready to work which means that you are algorithms and containers and stuff like that. I can start using concepts and you get the benefits right out of the box with C++20. There's work going on the function declaration like syntax. That's not settled yet and my guess is you won't get the concept type name introduces. If you don't know what that is, well tough, you can find out and anyway, you probably won't be able to use it in production for another couple of years. It's all available in the GCC implementation now. So my main sort of thesis here is that genetic program is just programming and my aim is to make this more true than it is now. And this implies that we need to improve some of our type checking to make type checking for generic code much more like checking for ordinary code. Eventually, the generic code will be ordinary code. We need to improve the syntax. The template syntax is clunky. It has been clunky since the simplest syntax didn't fly in the 80s. And we have to organize our code for generic and non-generic code in the same way. Not all of this header stuff or templates and .cbp for code, that's the modules stuff so I'm not going to talk about that. So basically there's a history to this. In the '80s, most of the '90s, if you wanted generic code in C++, you ended up using macros and I have a paper from '81 that says we need generic programming and macros will just do it for us. I was right about the first part and I was very wrong about the second part. Macros just poisons everything including your IDE and your editor and scrambled your brain so we have to do better than that. In '87 and on so now, I have some fairly specific aims for templates. I want them to be flexible. At the time, I said I don't want a language that can only do what I can imagine. I mean maybe my imagination is good but sure, it isn't as good as the union of people in a room like this and I want a zero-overhead, otherwise, people are right this sort of ugly pointers and array kind of code that they then think is more efficient, it often isn't and it's certainly less maintainable, than a good generic code. So it had to have zero-overhead, this is C++ has to be used for really critical embedded system stuff, it has to be used for high-performance stuff and it is today. And then of course, I wanted good interfaces because good interfaces is essential for large software. That's how we partition our code. We only have two ways of simplifying code. It's abstraction and divide and conquer. Divide and conquer means putting a barrier between two parts of the code and we get there. And as I used to say, two out of three ain't bad but it isn't good either. So I've been trying to figure out how to get away from the basic templates, unconstraint templates, header-only organization because it's fundamentally not right. It may be good enough. We've done superb things as a community in this period but we can do better. Okay, so let's take the time machine, go back to '78. And that's how we wrote code. This is K&R code. Say that square root returns a double. We give it a two and it crashes, of course because two happens not to be a double. Well, so what? Well, we didn't say it was a double. All we can say is we can go over to the source code and look at it and say that square root takes an X and it treats it as a double. It does not say you must give it a double or you get an error, get a runtime error. No, you get a crash. And I had sort of one look and another look at this, couldn't quite believe what I was seeing and made some changes in the last, in the first two months of the C++ project. See the classes that was caught, so now we can write double square root of double. I mean I want my square root and I want the declaration to say that it expects a double so that if we get square root or two, I get the right answer. It converts to two to 2.0. Similarly, if I give it some rubbish like a string, I get an error right there. This made a huge difference and I also cleaned up the syntax so that the definition now looks like declaration. And if you've been writing C++, you probably never seen anything else. If you've been writing C in the last sort of 30 years, you've been seeing things roughly like that and it's an operation like that I think we're trying to do with concepts relative to checking. Go back to '88 and we're saying that there must be a type which we will use as an iterator. And since we don't know too much about the interface, it just says there must be a type and we'll use two of them. It has to be in the header file so that we can do some compilation and I can say a vector of integers, that's fine, list of integer's fine, vector of S, fine. Everything works fine so we start using it. And then sorting vectors happens to work. Sorting lists doesn't work. From deep down in the implementation of sort, we will be told that there is an absence of a subscript or a plus or something to some type that we probably haven't heard of because it's an implementation detail. And if you want to sort the vector of S, well, because we couldn't get the definitions of equality in less than four types, it'll just tell you that you can't compare two structs. And the error messages are spectacularly bad. This is because we have duck typing. If it looks like a duck, if it waddles and it quacks, it's a duck. Unfortunately, of course, it could be a rubber ducky or something like that and we get these strange errors. We really want to be able to say that we want something better than just a type. And on the other hand, templates was a massive success. It's one of the things that kept C++ going and at the edge of things, we have flexibility, type safety, specialization for irregular types and the basis of template, lot much, template metaprogramming and a lot of type based optimizations. The result is great flexibility, great performance. And has huge flaws, as I pointed out, the syntax, I mean, even its mother couldn't appreciate it. Duck typing, error messages. The overloading with templates is really quite complicated. Code organization gets messy and the compilers get slow, very slow. We have to do something about it and I would like to address all of these aspects, not just fiddle with the corners of it. So let's see what I want and what we are getting. I would like to say that sort takes a sortable. Concept is a specification of what is sortable. And you can look it up in the standard. It says that you have to have a beginning and end. Being a sequence. It has to have random access and a value type. The element type has to be something you can compare. Fine, unfortunately, in the previous 20 years, compilers and users don't read the manual, however, now, we can write this so that it works. I am using the concept TS notation just now because then, I can test my code. This is not likely to become C++20 but it's in the TS. So, if I sort a vector, it matches the requirements of a vector of integers. It matches the requirements of sortable. List doesn't because it doesn't have a subscript, doesn't have random access and sort of the Ss doesn't because value type doesn't have the comparison operator. So I get an error right there and it should be readable. They will become even more readable over the years when things get tuned to use concepts well. And now, I can now sort anything that's sortable and the implementation of sortable could simply be to call the old sortable. And if you want to be more flexible, I can say I actually would like to sort lists even though they are not sortable. They don't have random access and so we just define the notion of something that lists like which has the properties of being a sequence with elements that you can compare and I can implement them by putting them into a vector sorting them and putting them back again. That's simple and quite often, a reasonably performing regulation and if we do this, once it sees the list, it will say oh, I can't do the simplest sortable but because of lack of property but I have enough properties to call the list so we'll do it. So we're getting the overloading like we got the overloading for ordinary types in the standard language, well, almost 40 years ago. And the rules for overloading, you can look at them up, a much simpler than four basic types. And by the way, as ranges are now coming, we can simplify. See, why do I have to say begin and end all the time? I mean one of the principles that we're trying to work towards is to make simple things simple and the simplest case of sorting a sequence is to sort all the elements of a container, anything, we just give it the whole range and it'll figure out what the details are. So things are improving. Notice also, I didn't say what the element type of the vector is. I can now deduce it. We are moving ahead and it's getting simpler to write good code. So, if we look at it, when I want to make ordinary code and generic code the same, I have to think about types and I have to think about how concepts fits into a type system. And a type basically specifies what operations I can use on an object implicitly or explicitly and it relies on function declarations and language rules to make sure this works and in addition, a type specifies how an object is laid out in memory. So it says, what can you do to an object and how can you make the object. A concept on the other hand, basically specifies how you can use an object. How implicitly or explicitly what operations you can use and that is specified in terms of something called use patterns, basically expressions and it reflects the rules of the language. And it says absolutely nothing about the layout of the object. And ideally, that would be the only difference between types and concepts. We are close to that. So you can think about simple objects of concepts, concepts that only take one argument as basically something that is how to use an object as opposed to how to make it. Okay, so here's an example. Types and concepts. I have here a concept which is same which is that a capitalized Int is really an int. And I can now start writing code with that concept. So x1, it will take anything that is an int and seven is an int so it'll do it, or I could use the integer directly. I can do operations and again, I can say, for the capitalized Int, I'm saying the result must be something that isn't int and the other one it says it is an int. And I can pass arguments and I can overload on it. This looks very, very similar and it is deliberate. I even thought of using a font that'll make it easier to tell the difference between the capitalized Int and the lowercase int and decided no, actually, the point is they're similar. The syntax here made immovable objections in the Standards Committee so it's unlikely you will be able to say sort a sortable. You will probably being able to say sort a sortable or throw stuff. People seem to like that better. It's a compromise proposed by Ville Voutilainen. So you can get very close to what I'm saying here. One of the main reasons this is a discussion is sortable of ref ref. if that was a concept then would be a template and the ref ref would be a forwarding reference. If not, it will be an r-value reference. I have taught concepts about five years. So, many dozens of people talk to many hundreds of people, I've never seen this kind of stuff in real life but that's a fact to the Standards Committee and I think I can live with what we are likely to get. So, that's sort of as much as I'm going say about what the technicalities about concepts. I'm going to talk about what benefits we might get out of it. By the way, my section breaks has people who contributed to this. Andrew Sutton there is the initial implementer of the stuff you can get to see now. And he's worked very hard on specification and implementation. So basically, concept supports good design and they are doing to design using templates roughly what classes did to ordinary programming. It allows us to structure our code better, it allows us to think about code better. If I'm going call something with a couple of points like draw a line, you can do it the old way, int, comma, int, comma, int, comma, int, comma, int and start wondering what the ints mean or you could have a point comma point or point comma box and be more specific about what your sign is. That kind of way of changing the way you think is what we're after. It gives better reliability and better maintainability. I have some practical experience with that. And again, for overloading, that's important because overloading is the basis of generic programming. If things aren't called the same when they're doing the same thing semantically to different types, you can't write generic code. We have to go there. So, let's see some example here. Here's the classical example. The slightly simplified version of advance from the Standard Library. We can say that if we are given a forward iterator, we have to do things the slow way. Dum-ti-dum-ti-dum-ti-dum-ti- dum, go forward. If I get a random access iterator, I can just go or there in one hop. This is a very important difference and we have it in the Standard Library. Now, we can write it as simply as this. Basically, give it a vector and advance is a very simple operation, or one. If we give it a list, it will be relatively slow operation, OM, and basically getting this kind of stuff simplifies our code relative to what we have to write today and makes it much more similar to other kinds of code. And note that we are not actually saying you have to write a concept hierarchy and make your code rigid and only do the things that has been pre-declared to work. Concepts are predicates, we just figure out which predicate matches the best and get on with it. The code is simpler. So yeah, as I pointed out, overloading is fundamental to generic programming the way we do it in C++. We have been using a lot of traits which can be quite complicated. If you looked at code using enable_if, you know it can be headache-inducing and also, the workarounds using these programming techniques on basically on type code, the fully generic stuff, it gets quite complicated and slow to compile. Type checking happens at the end at the very last moment and that's, at least it's type safe for some definition, it's type safety but it doesn't give the errors upfront and it gives the compiler a hard time. So let's see an example. Conditional properties. They're very widespread these days. Basically, we want to say that something like a class offers a property if and only if another type behaves in a certain way. So here is the classic pointer type. Smart pointer. It could be a unique point, it could be a shared point or something. All of them does the equivalent to what you see there. You have an operator dereference if and only if the thing with the element type is a class. Otherwise, you have to dereference. So that's expressed very directly. You get a dereference. It requires that T is a class. Take a more complicated example, I have a class pair. Still borrowing examples from the Standard Library and still capitalizing my type so that you know it isn't really in Standard Library. So I want to be able to make a pair out of two values and I want to make the pair out of two values if and only if each of the two values can be converted into the appropriate type of the pair. And so I write this. There are two element types. if their types are convertible to the appropriate, da-da-da-da-da. In other words, the code reflects very directly the way I expressed what I wanted. This is nice. To compare, for those of you who haven't seen too much enable_if code, here's the simplest version of the pointer version written the old way. It says that there's a, there's an arrow operator, dereference operator if, well, you can see the stuff there. This is sort of painful and particular, it's not universal, you can't use the same technique everywhere. I was thinking of showing the pair constructor and I decided not to because I had trouble fitting it on a slide. For starters, there's no place in a constructor to use an enable_if. Secondly, you have to deal with the variety situations. It gets very messy. Concept maps the way we think about our problems, the workarounds do not. So we simply cut out a part of the thought process. That's good. Some people who has tried to use auto and fully generic stuff has find that it leads to some problems. Every new feature get misused and overused. That's fine, I love auto and so does a lot of other people so it gets you all used. and one thing we found was that people call a function and they put the result into auto. That's reasonable if there's generic code. You don't know the exact type or you don't want to bind it to a particular type just yet so you just bring the generic code forward and you get things like foobar x or y, you put it to some value or some type. Fine, except we find that the programmers keep looking into the header files and flipping forwards and backwards in the code and readability is seriously decreased. This becomes a bug source. So, the response for now has been put a comment in. Every time you assign something that's not obvious, really, it's alpha type, put a comment on it. Sure, make_shared, you don't have to have a comment because you know make_shared makes a shared pointer but a lot of cases, if it goes beyond that, you have to put comments in and your code gets uglier, larger and comments are not always right. The concept, you can say well I'll take anything as long as it's an input channel. And you can do that in any context. That clears our code a lot eliminates programmers flicking back and forth between different parts of the code which is very distracting and breaking concentration and you just get much better code. Readability is one of the benefits of concepts. And then, I don't know. Familiarity is a strong force but you look at that template there, it's really quite clunky. And for new things, there are scary people want prefix keywords and that's how we got to here. Names become very important because there's not really a type system here in play that says what the type name really means. I mean type name input iterator means I hope that the input iterator is an input iterator. It's just a matter of hope. And this was what we got out of some historical process where people were a bit panicked or templates, they were very new at the time. When we can be specific? Things get far more readable. The version up there is slightly longer but it says much more. It says I'm going to get an input iterator, now, take any, I'll compare and I'll take any other type as long as it's in equality comparable with the value type. Let's see, I don't have a definition of value type there but that's the one that looks in and finds what the value type is, the element type. And with auto on type name, we have to sort to read the implementation again. We are back to the sort of the K&R style of C declarations. There's simply not information enough. And here, there's people who look at the top and says ooh, that's complicated. It isn't really. It's just unfamiliar for a day or two. I know from students that on day two, they wouldn't go back. And so, oops, I'm going the wrong way here. Sequences are expressed as pairs of iterators. We are going to move forward. We're going to get the range TS so we can stay instead of saying there's a pair of iterators, we can say I want a range however I expressed. and you get to the lower version there. It's important that we are now moving from the sort of language experimentation to the supported use of things with, with Standard Library support and such. And by the way, don't expect optimal readability from older code that has been bug compatibly moved forward to use concepts. And don't expect the most readability to come from the deep foundation libraries that has to have the ultimate flexibility. I have observed that the most benefits from readability actually comes from relatively simple and relatively new libraries written by people who understand concepts as opposed to people who understood the old techniques very well and replicates them using concepts. So, we still have a ways to go to overcome the ways of old thinking that leaves the complexity in place expressed with the new facilities. So again, back to this notion that auto and type name is the weakest form of typing, simply says, it's a type. In theory, we could actually do without having auto in the language. Look at that concept there, capital Auto. That's the way we could do it. If we started designing C++ today, quite likely, the building feature auto could be eliminated. And my aim is that you would accept the, you can accept the concept wherever auto is now. That's backwards, I really would like to use the fully generic concept auto if and only if there isn't a more precise way of stating what I'm trying to state, and that's not so good. And again, this has been around for a while. I proposed auto if auto in the Standards Committee in 2003 and the screams of horror were rather loud. Basically, in C++, we tend to rely on types and find things like void star and sort of suspect, it's a code smell. And I think we will get to the point where we think the type name and auto will be, well, a code smell. If they're there, somebody hasn't thought it through that at least, if you have an auto or type name T, there will be required clause coming later to see what it means but what we really need to get away from this fairly primitive thinking that we take a type and we do something with it and we try and write code that doesn't work if you get something that is slightly wrong and anyway, it gets complicated. So concept will change the way we think about it. It's not just a hope. It's what I have observed again and again with people who have learnt this kind of stuff. And this is not just support for business as usual. This is major, it changes the way we think. As I think I've said, I'm not keen on individual language feature talks and details talk. This is not a detail. This changes the foundation. And the community as a whole is going to be slow as usual. It takes a long, long time to get millions of people to change their mind about anything. And there are people who will never change their mind but individuals can do much better. So, even if we can't get everything we want in all the code now, maybe you can do better in your local code and maybe you can start experimenting even if you can't deploy it yet. That's what I and others started doing a few years ago. It works. First experiment, figure out what works in your context, move on and it can get to the production level. GCC has pretty good support for concepts. Clang is coming. I believe Microsoft is thinking hard about it and it's not really that hard to implement once you get going and the Standard Library has it so come C++20, we should all be there, so, it's time to get ready. Concepts weren't born yesterday. There's a lot of people says oh, it's new. It's dangerous, or as opposed to oh, it's new, it's great or it's new, it's really should have been something else. No, it shouldn't have been something else. We have spent a lot of time figuring out what fits with C++ and how to work it in, how to work the details. Alex started in '81 called algebraic structures and then he's been calling them concepts since somewhere in the '90s, early 90s, I think. No, no, no, no, late '80s. And I tried to find a way of constraining templates in '88, it failed and either I know anybody else knew how to get all three properties I wanted but we have. The STL was specified in terms of concepts even though there's no language support for it, it's a fundament way of thinking and therefore, it makes sense to talk about concepts even if there's no language support for it and then there's a lot of history here, I'm not going to go into it. That's a different talk but don't think it's something new or something totally malleable. Good people have worked hard on this stuff especially him. Okay, I haven't actually said that much about what is the concept and now, I should. And Alex said concepts are all about semantics. This might surprise you because there's no semantic part to the language support, however, it says what kind of properties a type must have, how can you use it and you have to think about what that means, what makes sense. So basically, technically, concepts are compile-time predicates. ForwardIterator<T>, it's true. If T is a forward iterator and it is false otherwise. And that can be used in the language and the language rules, that's the idea. What a forward iterator is, we can define somewhere else. We know what it is, we can look it up in the standard. And concepts are fundamental. They tend to represent fundamental concepts of our domains. So, if you're mathematically inclined, you have concepts like monoid, group, field and ring. In C++, we have input iterator, forward iterator, by directional iterator, random access operators. These are there. Today, we just have to represent them with language support. And so, we've always had concepts. I mean, you read K&R C, the first definition says an integral type is, an integer type is, these are concepts. Now, today, we can actually represent that in C++ but we've been using that for some definition of we for more than 40 years. And we, yeah. We have direct language support. So this is philosophy, you have Plato. This is the engineering. Archimedes, he's an engineer. And we must learn to use the techniques well, not just philosophy, but actually practical use and practical support. And the concept is good if it represents well-thought out concepts. It is not the minimum requirement for an implementation. We've been spending some time doing lifting and trying to find the absolute minimal requirements of an algorithm. That's not it. The ability to add things is not a fundamental thing for a large group of things. The ability to use ++ is not. You need something more well-thought out and there's no semantics to an individual operation but there is a semantics to a combination of operations like plus, minus, multiply and divide and good concept should support interoperability, so. Hmm, okay. A lot of people think about concepts as types of types and that's not it. You don't do too much harm thinking about a concept that takes a single argument as a type of a type, however, most concepts take more than one argument. If you have a template that takes two type arguments, almost by definition, there will be some relationship between those two type arguments. Why else are these type arguments to the same function? To same algorithm? There has to be a relation. You're using them in combination. The second you have two arguments of different types, you need a concept with two arguments and you're out of the type of type world. The other thing is that, like templates, concept can take value arguments. It's not that common just now but since we now have value arguments of different types in C++17, 20, it'll become more common. So, some of the concepts takes things like type and, and the value. This is not type of type kind of stuff and if you look at it, that means that concepts are not type classes and they were not meant to be type classes. It supposed to give you implicit conversions, mixed type operations which people have insisted on since Fortran and that type theorists have disliked since about the same time but this C++, we have to serve the C++ styles of uses and C++ users, they are not expressed in terms of sets of functions either. We tried that, it didn't scale. So one thing to remember, when you define concept, when you think about concepts is describe the concept for clusters of operations. I mean, plus, minus, multiply, divide and then you also probably need plus equals, minus equals, plus plus and such. For stacks you have push and pop and very rarely, does a concept characterize a single operation. HasPlus and HasMinus, a very suspect when you see them as concepts because they don't actually work in lots of places and they're used for ad hoc combinations of features and you get a set of operations that doesn't actually interoperate. So, you have to think about that. Here's a plug and play example. I wrote a simple implementation of a sum. Could have been accumulate or something but I wrote it in terms of plus equals. If I did the minimal dependency on that, I would have a dependency on a plus equals, plus equal about, something like that. The way of the dreaded ables. If your types have an able at the end, think a little bit harder. There are useful concepts that is named like that but most of them aren't. So, basically, when I want assistant constraint for that algorithm there, I have to think how else might I have expressed that algorithm. Should I just take plus equal or should I take plus equals and plus an equals? Basically, some kind of number is a better answer because you actually also want to have copyable unmovable, things you didn't think about just when you were doing it so you want to express the concept, you have to raise the level of discourse to something that makes sense basically in isolation. What is it that I'm really relying on? What is the fundamental concept we're doing with here? It's at least an additive monoid but I would say a number. And it's not just for algorithms. Here's a piece of code which happens to be a very minor simplification of some real code. It is an input channel, it takes some transport in a message decoder, what's an input transport? Well, as concept that says what it is and what's a message decoder? It's a concept that says what it is, basically saying what you can do to them and then you build up some context and then you have a variadic, variadic template here that is used to initialize the representation of the transport. This kind of stuff is really quite hard to write and understand and it's really hard to explain to new developers unless you have the conceptual framework provided by the concepts that also gives you the error handling if people misunderstand this kind of stuff. So you can build it, use it for large frameworks. Let's see, how do we define concepts as Gabby Dos Reis who work with me and others for many, many years for building up this kind of stuff. If you are going to use some concepts, obviously, the first choice is to find some concepts that somebody else has built. I have a slide of some sources but basically, the range library and the working, (audio cutting off) standard has examples. But if you have to build your own one, the best thing to say is that you can build it out of existing things. So, I talked about sortable. A type T is sortable if it is a sequence meaning it has begin an int, has random access means you can subscript an end and this value type is comparable, it has the operations there. This is not brain surgery, this is not rocket science though I'm sure we're going to use this in stuff for brain surgery and rockets. But this really is just a notation for the way we talk about these things. We have hit some fundamental concepts and it becomes easy to talk about them, easy to write them down. If you go down and want to define some of the simpler concepts directly instead of using things done by others like in every other area, you get to more complication and more trickery. It's easy to say square root of two but if you're going to write a square root, you have to know a little bit more. Are you going to use Newton-Rapson and how do you express it and is it a better algorithm? The minute you go down one level of abstraction, things gets more complicated, sometimes, very much more complicated but in here, it's fairly simple. I want a type to be equality comparable, comparable to equals. So there is a support in a language core requires which is that it can specify what the properties of expressions are. So it says that if I have two Ts, they have to be able to be compared to equals and non-equals and both cases, they have to return a bool. It's, again, not brain surgery but it's more complicated than that and you can get to slightly more complicated things. The way you get closer to the core language, you have to represent the facilities of the core language a bit better. So, a sequence requires, it has to be a value type. There has to be an iterator type and those are things I've just defined up there and the must be a begin that gives an iterator. There it is. There has to be an end that gives an iterator and the input iterator. Sorry, the iterator of T has to be an input iterator. I mean it's not just returning a type called an iterator. We can actually say that it is an iterator or else, we're in trouble. And by the way the value type of the iterator must be the value type of the type T for comparable. So that's one way of doing it, now, we're getting down to the level. We don't usually get much deeper than this but if you look at the definition of the range library, you can see that as we go down closer to the hardware, to the trickier bits in the language, they get more complicated. If we can stay there at the top slide, it's better and if we can stay out of this, it's even better. Like our fundamental functions like square root or sort, we get them out of the library. So do we get our concepts, there are in the working paper, a concept session which has concepts so you will never actually have to do equality comparable and such because they already understand it. Ranges, just about anything to do with algorithms and iterators and there's more places to find them. One thing to remember is I emphasize the importance of complete concepts with semantics make sense, they are fundamental. How do we get there? Well, there are two things. During development, we are almost going to get it wrong the first time. So we need to get there somehow. Secondly, sometimes, we need building blocks. So take an example here. Here, is sort of an ad hoc thing. It says that I requires something that you can add. That's usually a mistake. I consider requires requires a code smell. If you see that in your code, you probably haven't thought hard enough because usually when we want plus, we also want these other properties like you can get a+b but you can also increment and you can copy the thing. And quite often, you want to construct it from a zero, things like that. So if you write some in terms of a concept, you can improve it as you go along. This kind of requires requires which I've seen in far too much code done by people who are just coming to concepts. They think, well, I know the syntax, I can write these things. Just show me the syntax and I'll write. You get this kind of stuff and these requirements starts growing, growing, growing and they don't lead to interoperability because each operation is done by itself. What you need to do is to think about what can you do, what can you build up. Now, addable is one of these dangerous addables. So you think is it really what I want? Don't I want a number? Don't know what minus also? If I don't want minus, why why don't I? The minute you generalize sum to accumulate, you are up into the next level of abstraction where you need a proper concept to constrain what you can do. There's been people complaining about you can get accidental matches. If we are calculating what use of a concept matches various concepts, you can get things that could accidentally match. Now, I picked here an example from the old days of object-oriented programming where people were worried, sometimes, reasonably. Drawable, I define something drawable. It's something that you can draw. Be suspicious, it's only got one operation. It's unlikely to be a good concept. It may be something we did just at the beginning of a development before we knew exactly what it was but be careful. It's got a single operation, it's called able. Be careful. Anyway, so, we make a shape. It draws, we make a cowboy because in the game industry, we're drawers, and so now, we can do a draw_all and it draws all. Now, this is all right if draw really is the shape that draws. It's not so all right if it pulls a gun. So, that's an example from the early days of object-oriented programming just translated into modern terminology. Accidental matches can happen but really, that's a bad concept. It doesn't represent anything fundamental. If you have done this properly, there would have been draw operations than just draw and it's unlikely the cowboy would have had them more. Similarly, for a cowboy, there would be operations that probably didn't fit with a shape like get on the horse. So the accidental match can happen, it definitely can. Classic examples, input iterator and forward iterator, they only change in their semantics, not in the set of operations. And if they do, you can add disambiguation operator. I mean there's things that forward iterator can do that input iterator is cut and I go back to the beginning operation or something like that, it's not that hard or you can use a trait class, they still have their uses. But beware of the single constraint concepts. Here's a thing that I found. I started like a lot of people with concept like a number that had the four operations and then I realize that I needed that one then I realized I needed that one but notice one thing. My initial concept, the incomplete concept were useful. It caught a lot of the errors and allowed me to think and I could just improve it as we went along. What's missing here? The fact that numbers can be copied and moved. So I haven't quite gotten there yet but you develop these once at a time. Refinement of concepts in our minds is a gradual process as we learn and we improve our concepts. They have names so we can do it. One thing that concept do not do concepts as designed for C++, it does not catch all type errors and template definitions. This was a bit of a surprise to some of us if you read the early papers. It was one of the things we wanted and we didn't get it for a variety of reasons. Here, do we really want to catch this early? So forward iterator and it does an add. Yeah, it would be good if we could do it but as a matter of fact, doing that puts constraints on the performance, puts constraints on the compilation feature and it actually constrains things rather dramatically. And this kind of error will eventually be caught but only at an instantiation time. We're falling back to the bad old techniques for catching the errors. On the other hand, it allows us to write simple concepts simply and so to have fast compilers and be very, very flexible and I was, look, I have a set of rules that I'm following from the D&E, expressed in the D&E book. It's more important to allow a useful feature than to prevent every misuse. So, why not? Basically, we decided when we started redesigning concepts after the C++0x debugger that 90% of the benefit came from use checking and we figured out how to do use checking with the current notion of syntax. Gabby did some experiments. We know how to do it, it's just we got more and more worried that we were wrong to close the system like that. How do I build these concepts up slowly before I know all the constraints? How about debug aids? How about telemetry, logging? If the concept has to be complete so that you can check and catch everything that you use in the implementation that you didn't mention in the interface, then you have a closed system and you sort of have to reach a level of perfection before you can use it. And since you don't because perfection doesn't come early, you keep changing the interface. You want a debugger, you have to add debug ability in the interface. You want statistics added to an old concept, you have to add that to the interface. Now, all the user code might break. So we were beginning to get very worried about how you, how you do a transition from existing type of code to new code, how do you use old code from new code, how do you use new code from old code, we decided we are not going to touch definition checking for now. This actually requires serious syncing, not just, the fact that we know how to do it is not sufficient. Just because you can do something doesn't mean you have to. Okay. You can still do sum checking like static_assert. I want to know if my type matches the range concept, there it is. And for testing of my algorithms, I can just build what's called archetypes, sort of a class called, sort of X that has all the properties that I'm expecting and you feed that into a static_assert with my algorithm and you see if it works. The only snag is that you are likely to make the same mistakes when you are defining the architect type as you did when you defined the concepts. This can be, of course, mitigated by having different people borrow from such but just because there's no default, definition shaking doesn't mean that there's no checking you can do because, well, you can. you can just see it there, this works. Let's see. We would like to use high-level concepts more often. And so here's sort of a first cut on constraining merge. Merge is standard, standard algorithm and it's one of the more complicated ones. And so the first cut looks like this. I need three types. The first one is a forward iterator, the second one is a forward iterator and the third one is an output iterator. And you have to be able to compare and assign to all of these things. This is somewhat tedious and that's what the standard says but we are doing the equivalent of sort of doing primitive operations. In real world, we've learned we have to aggregate operations into functions, classes and such. And so this is a sort of, it's easy to make a mistake when you write so much and it's hard to read. One of my favorite phrases, headache inducing an accumulate is much worse. And by the way, this particular pattern appears, I think, four times in the standard. So what we do is we design mergeable which is the concept that requires three types and then does or the checking. So we need to get away from the most simple-minded things often starting out with single type concepts and then going into the relationship between those concepts and simply saying I want three types and they have the proper relationships among themselves for being mergeable. There's a more elegant way for doing that thing. I want to introduce three type names and they should be mergeable but that's not going to make it into C++20 though that is my favorite for expressing this idea and basically, then you just have to define mergeable and merger boy is the one that has the properties we require and obviously, this has the point, this has the advantage that if you write your code like this, you can improve that concept as you go along because the first time, you're not going to get it right. So, having it named is helpful, having it in one place to fix it is helpful. It is just like when you're defining functions. You are defining functions. So the principles of concept design is basically think harder about the semantics, think harder about the fundamental concepts. This is why concepts are core concepts, by the way and you have to think about what is universal and what can be used in many places as opposed to ad hoc. If you find you write a lot of similar concepts and a lot of long complicated concepts like if you see something like that, it's like seeing a whole lot of statements and a large function. You should eventually get used to thinking, oh, that's a code smell. Really, are there something that you can abstract from it and build something manageable like that. And you can actually predict that you're going to find in this case so it's better to introduce the name concept earlier even if you can't do all the details yet. Consistent set of properties, you make them concrete by using concepts. And basically, it's much easier to think about your code in terms of concepts. Again and again, I have said, met people says, well, I couldn't even think of this solution without concepts just like I've met people I can't even think about this solution without classes. It's a fundamental thing. It helps thinking. The major inspiration for a lot of this is elements of programming by Stepanov and McJones. John Backus was in this picture, so. It's interesting. He was the one that did Fortran, by the way. So there's a certain continuity in the programming world. And so concrete suggestions. Make sure that you can think about the semantics. When you see a concept, it's expressed in terms of syntax part. You should be able to think about it as having semantics. Eventually, we may get support for doing that. That will be called actions but we are not there yet. Incomplete concepts are far better than no concepts and basically, you tend to start thinking then you have simple concepts and let them grow later. Use named concept. Requires requires is code smell. You can use static_asserts to get upfront testing of your types and your concepts. To find the algorithms in terms of general types, the ideal is plug-and-play, not absolute minimization. And variables should be constrained with concepts so that you don't have to write in a fully functional style and you don't have to fix the type too early to be able to get readability. This improves readability. And basically, for those of you who haven't already been using concepts for months or years, try them. I have not personally met anybody who tried them and went back to on typed templates because they wanted to. It's quite often that you have to go back because the implementations are not universal yet and code bases cannot always be updated to the latest compiler on all of this stuff but I think it's much better if you try concepts, and so for withdrawal symptoms, for years after till they upgrade the compilers and the code bases then you don't think in terms of concept because you will not go back. Once you have used concept, you think in terms of them and it improves your code even if you don't have the language support. This is the underlying argument for that why this is fundamental and part of the basic structure of the language. And basically, good interfaces is key to good code. You can do it now. You simplify the code. There's a lot of complicated template metaprogramming using enable_ifs that gets radically simplified by using concepts. So if you're saying no, no, I'm not doing generic programming, I'm doing template metaprogramming. There's two things wrong with this. One is the word template. Metaprogramming doesn't have to be templates anymore. A lot of constexpr functions will help you. Secondly, concepts help with template metaprogramming because not all of template metaprogramming is on typed. And basically, the thing that people always say, well, you want concepts because it gives better error messages. No, you want concepts because of all of these other things and as a side-effect, you get better error messages because you have expressed your ideas more clearly so that even a compiler can understand you. Okay, and of course, fewer errors. That's what I have to say so questions? (attendees applauding) Do we have microphones? No microphones? You can probably yell loud enough for me to hear it. Yeah, so the question is that he'd gotten the impression that concepts were there to express algebras and my examples doesn't seem to reflect that idea and I don't think that idea is correct. It's not just for math, it's not just for things you have an underlying theory about. I showed mergeable which is part of the standard library. That's for an algorithm and I, I showed the input channel example where we're using concepts to constrain and specify actually the types that take part of a composition of things. So this was why I said it's not just for foundation libraries which a slightly stronger statement. I think it becomes very, very important in application programming and I've seen that again and again. I've seen it in industrial code and I've seen it very often in student code. - [Attendee] Bjarne, hi. - Yeah. - [Attendee] Can you go back to slide 51 and just. - That one? - [Attendee] Yeah, can you help me understand what the error was that didn't get caught and-- - Oh, an input iterator does not support plus, it only supports ++. So, this is the kind of mistake that you can actually see in real life. Somebody had in their head the notion that plus one and ++ was the same thing but it so happens that's not the way it's defined because plus one is to the type system, basically the same as plus 20 and you don't want to be able to go 20 steps into a list because that is an ON operation. And so we can't distinguish plus one from plus 10 or plus 10,000 and so the library is defined like that and so this is the kind of mistake that we would sort of like to catch but the side effects of catching that kind of thing is to close the interface around algorithms so that you can't debug, you can't have telemetry, you can't have gradual evolution and you can't have stable interfaces so we decided that this one, yeah, we'd like to do it but we don't quite know how yet. This takes more work. I think now, if you want to say something, please, find a microphone. - Yeah, to go back to the point about algebra is I think in a more general sense, you do have some examples here like advanced where you're using concepts to constrain and to create an overload set. You got advanced for forward iterators, for max iterators but then you have other examples like sort which sort takes something sortable, merge takes something mergeable and the standard swap takes something swappable and it's a little bit circular, right? In that case where we become unclear, well, is it sortable because I can pass it to the standard sort or is that a customization point where someone with advanced, you're using it as customization for it. Someone could add their own advanced that was less constrained or more constrained and it would pop into the overload set at the right point which sounds horrible but like that's the functionality you're enabling by like that as opposed to if constexpr or something like that inside the implementation. With sort, are we using it as a customization point? Is that the reason for creating an overload set? - Yeah, I'm supposed to repeat questions. This one is a little bit hard to repeat so I'll take it in chunks and repeat if I don't get to the real point. First of all, of course, we can do it with algebras. We've done the monoid, ring, vector space stuff. On the other hand, we want the open the overload that we get from C++ from the earliest days. I want to say if I want to specify the algorithms in the standard library with concepts and once you have done them with concept, you actually will be able to add your own versions to it just like you can add your own versions through overloading or if you're doing uptr and hierarchies, you can add your own versions by, by derivation. Now, some people call that ad hoc and definitely meant to support that also. - In that case, with sort, you're saying someone could add a more constrained sort that required sortable, add also something else and that sorta get picked. - [Bjarne] Sure. - Then you've got-- - I can use it both to get a more constrained version. So if you wanted a, a sortable that also could do foobar, whatever it is, you would simply take sort sortable and foobar so you can so you can get a narrower version, a more constrained version as opposed to what I was doing was I was opening up. How do you sort when you don't have all the properties? You can do both. I'm going for flexibility here, not for any particular theory. And in some sense, any concept in any algorithm can be more or less constrained. - Hi, so I've seen, in the examples I've seen so far, mostly just checks for existence of operations on types which is kind of something that we haven't been able to do before with enable_if itself. Why does it stop there and I'll go further and also check between relations of operations. For example, for the concept equality comparable. It's not just enough to check that there is the operation equal and unequal but also they should return the opposing value, right? - I think there are two questions here. The second one is why can't we check, see semantic connections between the functions of a concept. We had a design for that for C++0x called actions which I actually think is very good and could do exactly that. It expresses relationship between two operations and we just didn't think we could get that done now and we didn't want to complicate the process through acceptance in the Standards Committee by throwing in more features. - [Attendee] Is that is that where contracts could come in? I mean it's-- - No, no, contracts work on values. Concept works on types and it is still the type relations between the operations that we would be able to handle with, with concepts and with actions. There was a first part of your question that I don't think I answered. - [Attendee] I think I'm answered. - Okay, thank you. - I'm thinking about the operators which like plus unsigned integers which are not defined for the whole range of the thing or less than for floats, right? And you have the concepts which would cover these types like sortable of floats, right? Would you include float to sortable or not? I would definitely consider floating point numbers sortable and I would just ignore another number. There's been long, long debates about this and it relates to the issue of whether concept is a type of type. It is not, it's a requirement of what you get in and as I pointed out repeatedly, it may not be the complete constraint of the implementation. It is still the implementation's job to know what is coming in case, in case of a floating point number. It might get an end and it is the algorithm's job to decide whether I'd wants to do anything about it. - [Attendee] Right, but then, you wouldn't have the same semantics for example plus, plus, it has not the same semantics between instant loads, right? So if you have a number, that is not actually a number. - Do you want me to also check, sorry. Do you want me to also check overflow and underflow and everything? - [Attendee] That is actually hard. - It is very hard. Checking for another number is very hard. Checking for another number only when you've got a floating point type is very hard. If I was going to work things out for a small example, I might consider it but I think it's a wrong approach for real-world scalable code. - Yeah, but that would result in incorrect code. - Yeah, I mean it's a great help for thinking but I think trying to constrain the concept used to the things like that is wrong. I have another argument which I can't put my mind to just now. Another end number was discussed again and again and again, I suggest you go to Andrew Sutton's talk about concepts. He's really good at that point. And isn't two hours into a presentation, a little bit bool. - Hi, a bit concerned about the kind of coarse graining of concepts. So you kind of address this preemptively. You talked about how plusable was not a good concept and instead okay, we have numeric, right? I think one of the issues with this is that in general, when you're designing classes and especially for application developers, usually, it's better to error on the side of a constrained interface. So, if you don't need multiply then you don't write it. You can add it later if you need it. If you think it's confusing or misleading, you don't have it so we're in the situation now where if we start using this numeric constrain in many, many algorithms even though let's say multiplications not used like, I know accumulate probably isn't actually done this way but imagine if accumulate was done using numeric then suddenly, any type that I write that doesn't have multiply, we can't use with accumulate. So it's actually kind of encouraging people to like slot themselves into these concepts which it can be a good thing in some cases but I think sometimes, it's actually pretty bad if you're basically saying to people, if you wanna reuse this high-quality generic code, you better add like all these other operations you don't really need and the algorithm doesn't need. - This is a very old debate. Should you have absolute minimal? Yeah, I'm repeating the question. Do you have absolute minimal requirements or do you encourage people to build more complete types? And I don't think encouraging people to think about where their types fit semantically and put some extra work in is encouraging sloppiness on the contrary. You need to look at experience and my experience and other people's experience has been that encouraging plug-and-play, encouraging high level concepts is useful and important. Furthermore, I'm not being rigid about that. Notice I've said you evolve concepts and furthermore, you can have various levels of concepts. It would be quite reasonable to have concept for things that could be added and subtracted but not having multiply. So you have that flexibility. When you see a new feature, especially a major new feature, I find the programmers are amazingly good at imagining problems and they are actually quite often dramatically lousy in imagining benefits. And my view is that any language feature, any concept if I've used upon has benefits and potential errors and I consider software development fundamentally an engineering discipline as opposed to a branch of mathematics or type theory. And you have to evaluate the benefits and the disadvantages and then you have to observe what happens in real life and I have come to the conclusion after watching this kind of stuff and people using it for a decade plus that aiming for more general and more complete concepts actually improve code. - Thank you. - With introduction of templates, we had to change syntax to allow things to be constructed to move syntaxes intended for classes. So now we can use it for building types. So we made changes to the language to allow you to use it more uniformly. Now, with concept, I see similar danger. The concept will be easier to use obviously, but it could be realized in multiple ways. Do you see ways to change the language to help us realize the same concept in multiple implementations? - [Bjarne] I'm not sure I understand the question. - Imagine that we talk about sortability. In future you might be able to use it and do it using the spaceship operator, always, in the past, you'd collect some other operators, you'd still get the same thing semantically but it's really different implementation. - So the point is that you can implement things in different ways and you need some freedom to do this and that relates to the previous question. Do you define your concepts really tightly? Sortable is defined in terms of begin end and less than, that's what the standard says and that's what the concepts is. As a user, you then use the name of the concept. When the standard changes, say to, say that sort uses the spaceship operator directly, your code will not change. Your requirement on your users may change and you may have to fix that because the standard changed. But there's this interaction through the specification of the concept that gives you some freedom. And that your argument is an argument for the more general concepts as opposed to the minimal constraints. - I have a question about the relevance of constexpr in some of this. I know within a function, for example, if constexpr inside a template expansion has different properties in some ways than it does outside that, how would the constexpr interact with say function definitions and concepts it requires? - How would constexpr functions relate to the way it's used in concepts. There are currently not in concepts a way of requiring constexpr functions, for instance. That is something we've discussed over there. - I was thinking more of trying to express test properties using constexpr instead of forcing people to use enable_if. Inside a function, that's very simple but I was wondering if there is a way to do that with concepts as well. - I would like to see most users of enable_if disappear. They are more error prone, more complicated. You sometimes have to have both the enable_if of a condition, the enable_if on the opposite of the condition. If you have two predicates, you can end up with four versions of the code. This is horrid. That's eliminated by concepts, that helps. Constexpr functions fit with concepts because they both ways of expressing a predicate if they return a bool. So, it works together. There's a few rough edges, you cannot write a concept this is require constexpr function. By the way, code using concepts compile faster than code using workarounds. Eric Niebler reported two weeks ago that the range is TS that exists in two versions, and enable_if and the concepts compile 25% faster with concepts. Expressing things directly is better than representing things directly and we are winning on all accounts with concepts or the previous work around. - [Attendee] Thank you. - [Attendee] Regarding the idea of SFINAE and default template arguments, template deduction. What is the opportunity that exists between concepts as it exists right now and the ability for those to participate in template template arguments in deduction in SFINAE style sort of errors that you may argue-- - As far, okay, the question is how does template template arguments fit into it? I think it they simply fit into it. That is you can express concepts that involve template template argument. Again, this is a level of detail I don't want to go into for the fundamental things but I think you take the fundamental ideas, the fundamental techniques in the standard, you pull the crank and out comes the right solution. - [Attendee] Secondly, as well, with the ever widening gap between C and C++ for this matter, there have been many features that have been introduced into the language over the years that have allowed me to do certain things that I could still accomplish and compile with the previous generation of our language. How do concepts and their forward slash backwards compatibility for that matter restrict me from porting code or using development environments that exist in both C and C++? - Can you use concepts both with over compilers and C and C++. Well, concepts are not actually meant to be backwards compatible, obviously. And I think C is totally lost in this game because it doesn't have proper generics. You can't have concepts as a language feature supporting macros and in practical terms, if you need to work on a variety of environment, some are old, you can use things like if you restrict yourself to explicit requires clauses, you can have requires macro that turns into nothing for old environments and so what you can do is you can develop your stuff on a modern compiler, get the checking in place, do the testing on a modern compiler then throw the switch so that the concept becomes nothing and if you have not used overloading, it'll then run correctly on old compilers. A slightly more subtle version of that is to define your actual concepts as sort of capital concept macros that either turn into the concept for the modern compiler or to type name on the old one. Again, you lose overloading but you can compile with GCC 4.2 if you're unhappy enough. It's pretty horrid but there are ways of using older code, older compilers but you have to do nasty things. - [Attendee] And will there be the ability to default or specialize on concepts within template programming? - Will be thing for default and specializing? Specializing, yes, defaulting, I don't quite understand what it means in particular, so probably-- - [Attendee] Some other time, I suppose. - Some other time. - [Attendee] Hello, I'm coming actually from a theoretical physics background and I'm very excited about these developments that you've just talked about. I have a question much of or some of what can be achieved very elegantly with concepts has previously been achieved by inheritance through abstract classes and I wonder what is this take that you have on the position of abstract classes in the future with concepts being present? - So, abstract classes versus concepts. One thing I failed to emphasize because I've become so used to it, concepts is a zero overhead feature. There is no runtime cost. And that's important and I should have said so and I, once you get used to things, you forget. So for abstract classes, if you want a binary compatible upgradable interface, abstract classes are unbeatable. Just a set of functions. On the other hand, it causes indirect function call that can be expensive. Concepts are the opposite. There's no overhead, they're just compile time predicates. On the other hand, since concepts are independent of the layout of the objects they manipulate, they don't actually address the issue of binary compatibility at all. So I think they're sort of neutral. You have to orthogonal chores. - [Attendee] Okay, thank you. - [Moderator] So we do have 12 minutes till the next talk. If you would like to ask Bjarne question, maybe come to the stage and talk to him over there. We'll get to the next talk here. - Okay, thank you. - [Attendee] Thank you. (attendees applauding)
Info
Channel: CppCon
Views: 142,412
Rating: undefined out of 5
Keywords: Bjarne Stroustrup, CppCon 2018, Computer Science (Field), + C (Programming Language), Bash Films, conference video recording services, conference recording services, nationwide conference recording services, conference videography services, conference video recording, conference filming services, conference services, conference recording, conference live streaming, event videographers, capture presentation slides, record presentation slides, event video recording
Id: HddFGPTAmtU
Channel Id: undefined
Length: 98min 31sec (5911 seconds)
Published: Tue Sep 25 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.