back to index

Bjarne Stroustrup: C++ Concepts - Constraints on Template Parameters


Whisper Transcript | Transcript Only Page

00:00:00.000 | And then there's this idea of concepts that puts some...
00:00:07.000 | Now I've never even... I don't know if it was ever available in any form,
00:00:14.000 | but it puts some constraints on the stuff you can parameterize, essentially.
00:00:19.000 | Let me try and explain.
00:00:22.000 | So, yes, it wasn't there 10 years ago.
00:00:27.000 | We have had versions of it that actually work for the last 4 or 5 years.
00:00:34.000 | It was a design by Gabby Dos Reis, Andrew Sautin, and me.
00:00:40.000 | We were professors and postdocs in Texas at the time.
00:00:44.000 | And the implementation by Andrew Sautin has been available for that time.
00:00:53.000 | And it is part of C++20.
00:00:59.000 | And there's a standard library that uses it.
00:01:02.000 | So this is becoming really very real.
00:01:06.000 | It's available in Clang and GCC, GCC for a couple of years,
00:01:13.000 | and I believe Microsoft is soon going to do it.
00:01:16.000 | We expect all of C++20 to be available,
00:01:20.000 | in all the major compilers in 20.
00:01:24.000 | But this kind of stuff is available now.
00:01:29.000 | I'm just saying that because otherwise people might think I was talking about science fiction.
00:01:34.000 | And so what I'm going to say is concrete.
00:01:36.000 | This is real.
00:01:37.000 | You can run it today.
00:01:39.000 | And there's production uses of it.
00:01:41.000 | So the basic idea is that when you have a generic component, like a sort function,
00:01:52.000 | the sort function will require at least two parameters.
00:01:56.000 | One, a data structure with a given type and a comparison criteria.
00:02:04.000 | And these things are related.
00:02:06.000 | Obviously, you can't compare things if you don't know what the type of things you compare.
00:02:13.000 | And so you want to be able to say, "I'm going to sort something, and it is to be sortable."
00:02:20.000 | What does it mean to be sortable?
00:02:21.000 | You look it up in the standard.
00:02:23.000 | It has to be a sequence with a beginning and an end.
00:02:28.000 | There has to be random access to that sequence.
00:02:31.000 | And the element types have to be comparable.
00:02:37.000 | Which means less than operator can operate on them.
00:02:41.000 | Less than logical operator can operate on them.
00:02:43.000 | So basically what concepts are, they're compile-time predicates.
00:02:47.000 | They're predicates you can ask, "Are you a sequence?"
00:02:50.000 | "Yes, I have a begin and end."
00:02:53.000 | "Are you a random access sequence?"
00:02:56.000 | "Yes, I have subscripting and plus."
00:03:00.000 | "Is your element type something that has a less than?"
00:03:03.000 | "Yes, I have a less than."
00:03:06.000 | So basically that's the system.
00:03:09.000 | And so instead of saying, "I will take a parameter of any type," it'll say, "I'll take something that's sortable."
00:03:16.000 | And it's well-defined.
00:03:18.000 | And so we say, "Okay, you can sort with less than. I don't want less than. I want greater than or something I invent."
00:03:25.000 | So you have two parameters, the sortable thing and the comparison criteria.
00:03:31.000 | And the comparison criteria will say, "Well, you can write it saying it should operate on the element type and it has the comparison operations."
00:03:45.000 | So that's simply the fundamental thing.
00:03:48.000 | It's compile-time predicates.
00:03:50.000 | Do you have the properties I need?
00:03:52.000 | So it specifies the requirements of the code on the parameters that it gets.
00:03:59.000 | It's very similar to types, actually.
00:04:02.000 | But operating in the space of concepts.
00:04:07.000 | Concepts. The word "concept" was used by Alex Stepanov, who is sort of the father of generic programming in the context of C++.
00:04:19.000 | There's other places that use that word, but the way we call generic programming is Alex's.
00:04:25.000 | And he called them concepts because he said they're the sort of the fundamental concepts of an area.
00:04:31.000 | So they should be called concepts.
00:04:34.000 | And we've had concepts all the time.
00:04:36.000 | If you look at the K&R book about C, C has arithmetic types and it has integral types.
00:04:46.000 | It says so in the book.
00:04:49.000 | And then it lists what they are and they have certain properties.
00:04:53.000 | The difference today is that we can actually write a concept that will ask a type, "Are you an integral type?"
00:05:01.000 | Do you have the properties necessary to be an integral type?
00:05:05.000 | Do you have plus, minus, divide, and such?
00:05:08.000 | So maybe the story of concepts, because I thought it might be part of C++11.
00:05:18.000 | C-O-X, whatever it was at the time.
00:05:23.000 | What was the... Why didn't it...
00:05:27.000 | We'll talk a little bit about this fascinating process of standards, because I think it's really interesting for people.
00:05:32.000 | It's interesting for me.
00:05:34.000 | Why did it take so long? What shapes did the idea of concepts take?
00:05:41.000 | What were the challenges?
00:05:43.000 | Back in '87 or thereabouts.
00:05:47.000 | 1987?
00:05:48.000 | In 1987 or thereabouts, when I was designing templates, obviously I wanted to express the notion of what is required by a template of its arguments.
00:06:01.000 | And so I looked at this.
00:06:03.000 | And basically for templates, I wanted three properties.
00:06:07.000 | I wanted it to be very flexible.
00:06:11.000 | It had to be able to express things I couldn't imagine, because I know I can't imagine everything,
00:06:19.000 | and I've been suffering from languages that try to constrain you to only do what the designer thought good.
00:06:27.000 | Didn't want to do that.
00:06:29.000 | Secondly, it had to run faster, as fast or faster than handwritten code.
00:06:35.000 | So basically, if I have a vector of T and I take a vector of char, it should run as fast as you build a vector of char yourself without parameterization.
00:06:47.000 | And thirdly, I wanted to be able to express the constraints of the arguments, have proper type checking of the interfaces.
00:07:01.000 | And neither I nor anybody else at the time knew how to get all three.
00:07:07.000 | And I thought for C++, I must have the two first.
00:07:11.000 | Otherwise, it's not C++.
00:07:14.000 | And it bothered me for another couple of decades that I couldn't solve the third one.
00:07:19.000 | I mean, I was the one that put function argument type checking into C.
00:07:25.000 | I know the value of good interfaces.
00:07:27.000 | I didn't invent that idea. It's very common.
00:07:30.000 | But I did it.
00:07:32.000 | And I wanted to do the same for templates, of course, and I couldn't.
00:07:37.000 | So it bothered me.
00:07:39.000 | Then we tried again, 2002, 2003.
00:07:44.000 | Gabi Des Reys and I started analyzing the problem, explained possible solutions.
00:07:51.000 | It was not a complete design.
00:07:54.000 | A group in University of Indiana, an old friend of mine, they started a project at Indiana.
00:08:05.000 | And we thought we could get a good system of concepts in another two or three years.
00:08:17.000 | That would have made C++ 11 to C++ 06 or 07.
00:08:25.000 | Well, it turns out that I think we got a lot of the fundamental ideas wrong.
00:08:32.000 | They were too conventional.
00:08:35.000 | They didn't quite fit C++ in my opinion.
00:08:38.000 | Didn't serve implicit conversions very well.
00:08:42.000 | It didn't serve mixed type arithmetic, mixed type computations very well.
00:08:50.000 | A lot of stuff came out of the functional community.
00:08:55.000 | And that community didn't deal with multiple types in the same way as C++ does.
00:09:05.000 | Had more constraints on what you could express.
00:09:10.000 | And didn't have the draconian performance requirements.
00:09:15.000 | And basically, we tried. We tried very hard.
00:09:19.000 | We had some successes, but it just in the end wasn't...
00:09:25.000 | Didn't compile fast enough, was too hard to use,
00:09:30.000 | and didn't run fast enough unless you had optimizers that was beyond the state of the art.
00:09:39.000 | They still are.
00:09:40.000 | So we had to do something else.
00:09:42.000 | Basically, it was the idea that a set of parameters defines a set of operations,
00:09:51.000 | and you go through an indirection table just like for virtual functions,
00:09:55.000 | and then you try to optimize the indirection away to get performance.
00:10:02.000 | And we just couldn't do all of that.
00:10:04.000 | [ Silence ]
00:10:08.000 | [ Silence ]
00:10:12.000 | [ Silence ]
00:10:16.000 | [ Silence ]
00:10:20.000 | [BLANK_AUDIO]