Lex Fridman Podcast - Bjarne Stroustrup: C++
Episode Date: November 7, 2019Bjarne Stroustrup is the creator of C++, a programming language that after 40 years is still one of the most popular and powerful languages in the world. Its focus on fast, stable, robust code underli...es many of the biggest systems in the world that we have come to rely on as a society. If you're watching this on YouTube, many of the critical back-end component of YouTube are written in C++. Same goes for Google, Facebook, Amazon, Twitter, most Microsoft applications, Adobe applications, most database systems, and most physical systems that operate in the real-world like cars, robots, rockets that launch us into space and one day will land us on Mars. This conversation is part of the Artificial Intelligence podcast. If you would like to get more information about this podcast go to https://lexfridman.com/ai or connect with @lexfridman on Twitter, LinkedIn, Facebook, Medium, or YouTube where you can watch the video versions of these conversations. If you enjoy the podcast, please rate it 5 stars on Apple Podcasts or support it on Patreon. Here's the outline with timestamps for this episode (on some players you can click on the timestamp to jump to that point in the episode): 00:00 - Introduction 01:40 - First program 02:18 - Journey to C++ 16:45 - Learning multiple languages 23:20 - Javascript 25:08 - Efficiency and reliability in C++ 31:53 - What does good code look like? 36:45 - Static checkers 41:16 - Zero-overhead principle in C++ 50:00 - Different implementation of C++ 54:46 - Key features of C++ 1:08:02 - C++ Concepts 1:18:06 - C++ Standards Process 1:28:05 - Constructors and destructors 1:31:52 - Unified theory of programming 1:44:20 - Proudest moment
Transcript
Discussion (0)
The following is a conversation with Bjorn Strollstruck. He is the creator of C++.
Programming language that after 40 years is still one of the most popular and powerful languages in the
world. It's focused on fast, stable, robust code,
underlies many of the biggest systems in the world that we have come to rely on as a society.
If you're watching this on YouTube, for example, many of the critical backhand components of YouTube are written in C++.
Same goes for Google, Facebook, Amazon, Twitter, most Microsoft applications, Adobe applications, most database systems, and most physical systems that operate in the real world, like cars, robots, rockets that launch us into space, and one day will land us on Mars.
C++ also happens to be the language that I used more than any other in my life.
I've written several hundred thousand lines of C++ source code.
Of course, lines of source code don't mean much, but they do give hints of my personal
journey through the world of software.
I've enjoyed watching the development of C++ as a programming language, leading up to
the big update in the standard in 2011 and those that followed in 14, 17 and toward the
new C++ 20 standard, hopefully coming out next year.
This is the Artificial Intelligence Podcast.
If you enjoy it, subscribe on YouTube, give it 5 stars and iTunes, support it on Patreon,
or simply connect with me on Twitter at Lex Friedman's spelled F-R-I-D-M-A-N.
And now here's my conversation with Bjorn Straustrop. What was the first program you've ever written?
Do you remember?
It was my second year in university, first year of computer science, and it was in
alcohol 60.
I calculated the shape of a superlips and then connected points on the perimeter, creating
star patterns.
It was with a wedding on paper printer. And that was in college.
University. Yeah, I learned to program the second year in university.
What was the first programming language if I may ask it this way that you fell in love with?
this way that you fell in love with. I think I'll call 60 and after that I remember I remember snowball.
I remember Fortran didn't fall in love with that.
I remember Pascal didn't fall in love with that.
It all got in the way of me and then I covered assembler, and that was much more fun.
And from there, I went to microcode.
So you were drawn to the, you found the low level stuff
beautiful.
I went through a lot of languages, and then
I spent significant time in assembler and microcode that was sort of
the first really profitable things and I paid for my masters actually. And then I discovered
Simula, which was absolutely great. Simula. Simula was the extension of Elgol 60, done primarily
for simulation, but basically they invented upgitory into programming
at inheritance and runtime polymorphism when they were while they were doing it. And that
was a language that taught me that you could have the sort of the problems of a program grow with size of the program, rather than with the
square of the size of the program.
That is, you can actually modularize very nicely.
And that was a surprise to me.
It was also a surprise to me that a stricter type system than Pascal's was helpful,
whereas Pascal's type system got my way all the time.
So you need a strong type system to organize your code well
but it has to be extensible and flexible.
Let's get into the details a little bit.
What kind of type system did Pascal have?
What type system, typing system
did the alcohol 60 have?
Basically, Pascal was sort of the simplest language
that Niklaus Viet could define that served the needs
of Niklaus Viet at the time.
And it has a sort of a highly moral tone to it
that is if you can say it in Pascal, it's good and if you can't, And it has a sort of a highly moral tone to it,
that is, if you can say it in Pascal, it's good, and if you can't, it's not so good.
Whereas,
similar,
a large is basically to build your own type system.
So instead of trying to fit yourself
into Nicklaus Vierst's world, Christen Nugor's language
and all you undialse language allowed you to build your own.
So it's sort of close to the original idea of you build a domain-specific language.
As a matter of fact, what you build is a set of types and relations among
types that allow you to express something that's suitable for an application.
When you say types, stuff you're saying has echoes of object during a programming.
Yes, they invented it. Every language that uses the word class for type is a descent of similar. Directly
or indirectly. Christen Nüggor and Oliohandal were mathematicians and they didn't think in terms
of types, but they understood sets and classes of elements and so they called their types classes.
And basically in C++, else in similar classes are used to find type.
So can you try the impossible task and give a brief history of programming languages from your perspective. So we started with the alcohol 60
similar Pascal, but that's just the 60s and 70s. I can try the most sort of
interesting and major improvement of programming languages was the first
four-train because before that all code was written for a specific machine
and each specific machine had a language, a simply language or a simple or some extension
of that idea, but you are writing for a specific machine in the language of that machine. And Barker's and his team at IBM built a language that would allow you to write what you really wanted.
That is, you could write it in a language that was natural for people.
Now, these people happen to be engineers and physicists, so the language that came out was somewhat unusual for the rest of the world.
But basically, they said formula translation because they wanted to have the mathematical formulas translated into the machine.
And as a side effect, they got portability.
Because now they are writing in the terms that the human used and the way humans thought
and then they had a program that translated it into the machines needs.
And that was new and that was great and it's something to remember. We want to raise the language
to the human level but we don't want to lose the efficiency.
to the human level, but we don't want to lose the efficiency.
So, and that was the first step towards the human. That was the first step.
And of course, there were very particular kind of humans,
business people, different, so they got co-born state,
and etc, etc.
And similar came out, no, let's not go to simulate yet. Let's go to Elgol.
Fortran didn't have at the time the notions of not a precise notion of type, not a precise notion of
scope, not a set of translation phases that was what we have today,
lexical, syntax, semantic.
It was sort of a bit of a model in the early days,
but hey, they're just on the big breakthrough
in the history of programming, right?
So you can't criticize them for not having gotten
all the technical details, right?
So we got alcohol. That was very
pretty. And most people in commos and sirens considered it useless because it was not flexible
enough and it wasn't efficient enough and etc. etc. But that was a breakthrough from the technical
point of view. Then similar came along to make that idea more flexible,
and you could define your own types.
And that's where I got very interested.
Christian Newcombe, who's the main idea man behind Simula.
That was late 60s.
That was late 60s.
Well, I was a visiting professor in Osh? And so I learned
object oriented programming by sitting around and well in theory discussing with with with
Kaisnügel. But Kaisn once you get started in in full flow is very hard to get a word in edgeways where you're just listening so
It was great. I learned it from there not to romanticize the notion, but it seems like a big leap to think about or object oriented programming
It's really a leap of abstraction. It's yes, and
was that as a big and beautiful of a leap as it seems from now in
retrospect, or was in an obvious one at the time? It was not obvious. And many people have tried
to do something like that. And most people didn't come up with something as as wonderful as similar. Lots of people got their PhDs and made their careers out
of forgetting about similar or never knowing it. For me the key idea was
basically I could get my own types and that's the idea that goes further into
C++,
where I can get better types and more flexible types and more efficient types,
but it's the fundamental idea.
When I want to write a program, I want to write it with my types.
That is appropriate to my problem,
and under the constraints that I'm under with hardware, software, environment, etc.
And that's the key idea. People picked up on the class hierarchy,
in the virtual functions and the inheritance, and that was only part of it.
It was an interesting and major part, and still a major part, and a lot of graphic stuff,
but it was not the most fundamental.
It was when you wanted to relate one type to another.
You don't want them all to be independent.
The classical example is that you don't actually want to write a city simulation with vehicles where you say, well, if it's a
bicycle to write the code for turning a bicycle to the left, if it's a normal car, turn
right the normal car way, if it's a fire engine, turn right the fire and in way that out
and out of the, you get these big case statements and bunches of if statements such. Instead, you
tell the base class that's the vehicle, and say, turn left the way you want to. And this
is actually a real example. They used it to simulate and optimize the emergency services for somewhere Norway back in the 60s.
Wow.
So this was one of the early examples for why you needed inheritance and you needed a
runtime polymorphism because you wanted to handle this set of vehicles in a manageable way.
You can't just rewrite your code each time a new kind of vehicle comes along.
Yes, it's a beautiful, powerful idea. And of course, it stretches through your work, Lucy Buspos, as we'll talk about. But I think you've
structured it nicely. What other breakthroughs came along in the history of programming
languages, if we were to tell the history in that way.
Obviously, I'm better telling the part of the history that the Dessupeyth I'm one as
opposed to, to, to orn the path. Yeah, you skipped the hippie,
John McCarthy and list, one of my favorite languages.
But list is not one of my favorite languages.
Yes, it's obviously important.
It's obviously interesting.
Lots of people write code in it.
And then they rewrite it into CSE plus plus one.
They want to go to production.
Yes. write it into CSC plus plus one they want to go to production. It's in the world I'm at, which are constrained by performance,
reliability issues, deployability, cost of hardware.
I don't like things to be too dynamic.
It is really hard to write a piece of code
that's perfectly flexible,
that you can also deploy on a small computer,
and that you can also put in, say, a telephone switch
in Bogota, what's the chance?
If you get an error and you find yourself in the debugger,
that the telephone switch in Bogota on late Sunday night
has a program around. The chance is zero. And so a lot of things I think most about
can't afford that flexibility. I'm quite aware that maybe 70, 80% of all code are not under the kind of constraints. I'm interested in
But somebody has to do the job I'm doing
Because you have to get from these high-level flexible languages to the hardware
The stuff that lasts for 10 20 30 years is robust. Yeah, operates under very constrained conditions.
Yes, absolutely.
That's right.
And it's fascinating and beautiful in its own way.
It's C++ is one of my favorite languages and so is Lisp.
So I can I can embody too for different reasons as a programmer.
I understand why it is popular, and I can see the beauty of the ideas, and similarly with
with small talk. It's just not as relative,
it is not as relevant in my world.
And by the way, I distinguish between those and the functional languages where I go to things like ML and Haskell.
Different, different kind of languages, they have a different kind of
beauty and they are very interesting. And I actually try to learn from all the
languages I encounter to see what is there that would make working on the kind of problems I'm interested in with the kind of constraints that I'm interested in.
What can actually be done better? Because we can surely do better than we do today. You've said that it's good for any professional programmer to know at least five languages
as speaking about a variety of languages that you've taken inspiration from and you've listed
yours as being at least at the time C++ obviously Java Python, Ruby and JavaScript.
obviously Java Python Ruby and JavaScript. Can you first of all update that list, modify it? You don't have to be constrained to just five, but can you describe what you picked up also
from each of these languages? How you see them as inspirations for even you working with C++. This is a very hard question to answer.
So, about languages, you should know languages.
I recognize you about 25 or thereabouts
when I did C++.
It was easy on those days because the languages were smaller
and you didn't have to learn a whole programming environment and
such to do it. You could learn the language quite easily. And it's good to learn so many
languages. And I imagine just like with natural language for communication, there's different
paradigms that emerge in all of them, that there's commonalities and so on.
So I picked five out of a hat.
You picked five out of a hat.
Offer it, Ashley.
The important thing that the number is not one.
That's right.
I don't like, I mean, if you're monoglued, you are likely to think that your own culture
is the only one's periods for everybody else.
A good learning of a foreign language and a foreign culture is important.
It helps you think and be a better person.
With programming languages, you become a better programmer, a better designer, with the second
language.
Now, once you've got two, the way to five is not that long.
It's the second one that's most important.
And then when I had to pick five, I sort of thinking what kinds of languages are there?
Well, there's a really low level stuff. It's good. It's actually good to know machine code.
Even still. Even today. The C++ optimizer is right better machine code than I do.
But I don't think I could appreciate them if I actually didn't understand machine code
and machine architecture, at least in my position, I have to understand a bit of it, because you mess up the cache and
you're off in performance by a factor of 100.
Right?
Shouldn't be that if you are interested in other performance or the size of the computer
you have to deploy.
So I would go, there's a simpler.
I used to mention C, but these days going low level is not
actually what gives you the performance. It is to express your ideas so
cleanly that you can think about it and the optimizer can understand what
you're up to. My favorite way of optimizing these days is to throw out the
clever bits and see if it still runs fast. And sometimes
it runs faster. So I need the abstraction mechanisms or something like C++ to write compact
high performance code. There was a beautiful keynote by Jason Turner at the CPP kind of couple of years ago, where he decided he was going to program Pong on
Motorola 60, 800, I think it was. And he says, well, this is relevant because it looks like a
microcontroller. It has specialized hardware, it has not very much memory and it's relatively slow.
specialized hardware, it has not very much memory and is relatively slow. And so he shows in real time how he writes punk, starting with fairly straightforward low-level
stuff, improving his subtractions, and what he's doing is writing C++, and it translates
into into 86 a simpler, which you can do with Clang.
And you can see it in real time.
It's the CompileLikes Blower, which you can use on the web.
And then here are a little program that translated 86th assembler into Motorola assembler.
And so he types, and you can see this thing in real time.
Well, you can see it in real time. And even if you can't read the assembly code,
you can just see it. His code gets better. The code, the assembler gets
smaller. He increases the abstraction level, uses C++ 11 as a word better.
This code gets cleaner, it gets easier maintained
on the code shrinks, and it keeps shrinking. And I could not in any reasonable amount of
time, write that as simple as good as the compiler generated from really quite nice modern C++. And I'll go as far as to say,
the thing that looked like C was significantly uglier
and smaller when it became,
and larger when it became machine code.
So the abstractions that can be optimized, I'm haughty.
I would love to see that kind of visualization
larger code bases. Yeah, that might be beautiful. I can't show a larger code base in a one hour talk
and I have it fit on the screen. Right. So that's C and C++. So my two languages would be
machine code and C++. Right. And then I think you can learn a lot from the functional languages. So,
pick has glyML, I don't care which I think actually you learn the same lessons of
the expressing, especially mathematical notions really clearly and having the type system that's really strict. Then you should probably have a language
for quickly churning out something.
You could pick JavaScript, you could pick Python, you could pick Ruby.
It really make JavaScript in general.
You're talking in the platonic sense about languages,
about what they're good at,
what their philosophy of design is. But there's also a large user base behind
each of these languages, and they use it in the way sometimes maybe it wasn't really designed for.
That's right. JavaScript is used way beyond, I probably would have designed for it.
Let me say it this way, when you build a tool, you do not know how it's going to be used.
You try to improve the tool by looking at how it's being used and when people cut their fingers
or from trying to stop that from happening. But really, you have no control over how something is used.
So I'm very happy and proud of some of the things he plus-plus being used at. And some of the things I wish people wouldn't do, Bitcoin mining being my favorite example,
uses as much energy as Switzerland and mostly serves criminals.
But back to the languages, I actually think that having JavaScript run in the browser,
it was an enabling thing for a lot of things.
Yes, you could have done it better,
but people were trying to do it better
and they were using sort of more principles,
language designs, but they just couldn't do it right.
And the non-professional programmers that write lots of that code just couldn't do it right. And the non-professional programmers at right
or lots of that code just couldn't understand them.
So it did an amazing job for what it was.
It's not the prettiest language.
And I don't think it ever will be the prettiest language.
But that's not bigots here.
So what was the origin story of C++?
Yeah. You basically gave a few perspectives of your inspiration, of object oriented programming,
that you had a connection with C in performance, efficiency was an important, I think you were drawn to.
in performance efficiency was an important thing you were drawn to.
Efficiency and reliability reliability, you have to get both. What's reliability?
I really want my telephone calls to get through and I want to call it to you if what I am talking coming out to the other end. The other end might be in London or wherever.
So, and you don't want the system to be crashing.
You're doing a bank, you must crash,
it might be your bank account that isn't trouble.
There's different constraints like in games,
it doesn't matter too much if there's a crash,
nobody dies and nobody gets ruined.
But I'm interested in the combination of performance, partly because of sort of speed of things being
done, part of being able to do things that is necessary to have rely on the ability of larger systems.
have reliability of larger systems. If you spend all your time interpreting a simple function call, you are not going to have enough time to do proper signal processing to get the
telephone calls to sound right. Either that, or you have to have 10 times as many computers
and you can't afford your phone anymore.
It's a ridiculous idea in the modern world because we have solved all of those problems.
I mean, they keep popping up in different ways because we tackle bigger and bigger problems.
The efficiency remains always an important aspect.
But you have to think about efficiency, not just speed, but as an enabler to important things.
And one of the things it enables is reliability, is dependability.
When I press the pedal, the brake pedal of a car, it does not actually connect it directly to
anything but a computer. That computer better work.
Let's talk about reliability just a little bit. So modern cars have ECUs, have millions
of lines of code today. So this is certainly especially through autonomous vehicles where
some of the aspect of the control or driver assistance systems that steer the car, that keep it in the lanes on.
So how do you think, you know, I talked to regulators, people in the government who are
very nervous about testing the safety of these systems of software, ultimately software
that makes decisions that could lead to fatalities. So how do we test software systems like these?
First of all, safety, like performance,
and like security, this is systems property.
People tend to look at one part of a system at a time
and saying something like,
this is secure. That's all right. I don't need to do that. Yeah, that piece of code is secure.
I'll buy your operator. If you want to have reliability, if you want to have performance,
if you want to have security, you have to look at the whole system.
I did not expect you to say that, but that's very true.
Yes.
I'm dealing with one part of the system
and I want my part to be really good,
but I know it's not the whole system.
Furthermore, making an individual part perfect
may actually not be the best way of getting
the highest degree of reliability and performance
and so on.
The people say, C++ is not type safe.
You can break it.
Sure.
I can break anything that runs on a computer.
I may not go through your type system.
If I wanted to break into your computer, I'll probably try a skewering injection.
It's very true. If I wanted to break into your computer, I'll probably try SQM injection.
It's very true. If you think about safety or even reliability at a system level, especially when a human being is involved,
it starts becoming hopeless pretty quickly in terms of
proving that something is saved to a certain level.
Because there's so many variables, it's so complex.
Well, let's get back to something we can talk about.
And it actually makes some progress on.
Yes.
We can look at C++ programs and we can try and make sure
they crash this often.
The way you do that is largely by simplification. It is not the first step
is to simplify the code, have less code, have code that are less likely to go wrong. It's not by
runtime testing everything. It is not by big test frameworks that you're using. Yes, we do that
also. But the first step is actually to make sure that when you want to express something,
you can express it directly in code rather than going through endless loops and convolutions
in your head before it gets down the code. That if the way you're thinking about a problem is not in the code.
There is a missing piece that's just in your head.
And the code you can see what it does, but it cannot see what you thought about it,
unless you have expressed things directly.
When you express things directly, you can maintain it.
It's easier to find errors, it's easier to make modifications.
It's actually easier to test it,
and learn, behold, it runs faster.
And therefore, you can use a smaller number of computers,
which means there's less hardware
that could possibly break.
So I think the key here is simplification, but it has to be to use the Einstein
code as simple as possible and no simpler.
Not simpler.
But there are other areas with under-constrained where you can be simpler than you can be in
C++, but in the domain I'm dealing with
that's the simplification of Hamasca. So how do you inspire or ensure that the Einstein level
simplification is reached? So can you do code review? Can you look at code?
Is there, if I gave you the code for the 4DF150,
I said, here, is this a mess or is this OK?
Is it possible to tell?
Is it possible to regulate?
And experienced, the developer can do it code and see
if it smells.
Mixed made it for is deliberately.
The point is that it is hard to generate something that is really obviously clean and can be appreciated. But you can usually recognize when you haven't reached that point.
And so if I have never looked at the 150 code, so I wouldn't know.
But I know what I would be looking for.
There I would be looking for some tricks that correlate with bugs in elsewhere.
And I have tried to formulate rules for what good code looks like.
And the current version of that is called the C++ core guidelines.
One thing people should remember is there's what you can do
in a language and what you should do.
In a language, you have lots of things
that is necessary in some contexts,
but not in others as things that exist
just because there's 30-year-old code out there
and you can't get rid of it, but
you can't have rules as it says when you create it, try and follow these rules.
This does not create good programs by themselves, but it limits the damage and for mistakes, it
limits the possibilities of the mistakes. And basically, we are trying to say, what is it that a good program
or does at the fairly simple level of where you use the language
and how you use it?
Now, I can put all the rules for chisening in marble.
It doesn't mean that somebody who follows all of those rules
can do a masterpiece by Michelangelo.
That is, there's something else to write a good program.
Just there is something else to create an important work of art.
That is, there's some kind of inspiration on the standing gift, but we can approach the sort of technical,
the craftsmanship level of it. The famous painters, the famous cultures, was among other things
was among other things superb craftsmen.
They could express their ideas using their tools very well.
And so these days, I think what I'm doing, what a lot of people are doing,
we are still trying to figure out how it is
to use our tools very well.
For a really good piece of code,
you need a spark of inspiration and you can't I think regulate that. You cannot say that I'll take a picture only, I'll
buy your picture only if you're at least then go. There are other things you can regulate, but not the inspiration.
I think that's quite beautifully put.
It is true that there is an experienced programmer when you see code that's inspired, that's
like Michelangelo.
You know it when you see it.
And the opposite of that is code that,
is messy code that smells, you know when you see it.
And I'm not sure you can describe it in words,
except vaguely through guidelines and so on.
Yes.
It's easier to recognize ugly than to recognize beauty.
In code.
And for the reason is that sometimes beauty
comes from something that's innovative and unusual.
And you have to sometimes think reasonably hard
to appreciate that.
On the other hand, the message has things in common.
And you can have static checkers and dynamic checkers at finds at a large number of the most
common mistakes.
You can catch a lot of sloppiness mechanically.
I'm a great fan of static analysis in particular, because you can check for not just the language rules,
but for the usage of language rules.
And I think we will see much more static analysis
in the coming decade.
Can you describe what static analysis is?
You represent a piece of code
so that you can write a program that goes over that representation and look
for things that are right and not right. So for instance, you can analyze a program to if resources are leaked. That's one of my favorite problems. It's not actually all that hard
and modern C++, but you can do it. If you're writing in the C level, you have to have a
malloc in a free and they have to match. If you have them in a single function, you can usually do it very easily.
If there's a malloc here, there should be a free there.
On the other hand, in between can be
sure in complete code, and then it becomes impossible.
If you pass that pointer to the memory out of a function
and then want to make sure that the free is done somewhere else.
Now it gets really difficult. And so for static analysis you can run through a
program and you can try and figure out if there's any leaks. And what you will
properly find is that you will find some leaks and you will find quite a few places where your analysis can't be complete.
It might depend on runtime, it might depend on the cleverness of your analyzer.
And it might take a long time, some of these programs run for a long time. But if you combine such analysis with a set of rules,
it says how people could use it, you can actually see why the rules are violated. And that stops you
from getting into the impossible complexities. You don't want to solve the whole thing problem.
will come complexity is you don't want to solve the holding problem. So static analysis is looking at the code without running the code.
Yes. And thereby it's almost not a production code, but it's almost like an
educational tool of how the language should be used. It guides you like it is
best, right? It would guide you in how you write future code
as well and you learn together.
Yes.
So basically, you need a set of rules
for how you use the language.
Then you need a static analysis that catches your mistakes
when you violate the rules or when your code ends up
doing things that it shouldn't
despite the rules because there's the language rules, we can go further.
And again, it's back to my idea that I'll much rather find errors before I start running the code.
If nothing else, once the code runs, if it catches an error at run times, I have to have an error handler. And one of the
hardest things to write in code is error handling code, because you know something went wrong.
Do you know really exactly what went wrong? Usually not. How can you recover when you don't
know what the problem was? You can't be 100% sure what the problem was in many, many cases.
You can't be 100% sure what the problem was in many, many cases. And this is part of it.
So yes, we need good languages, we need good type systems.
We need rules for how to use them.
We need static analysis.
And the ultimate for static analysis is course program proof, but that still doesn't scale to the kind of systems we deploy. Then we start
needing testing and the rest of the stuff. So C++ is an object oriented programming language
that creates, especially with its newer versions, as we'll talk about higher and higher levels of
abstraction. So how do you design?
Let's even go back to the origin C++.
How do you design something with so much abstraction
that's still efficient and is still something
that you can manage due static analysis on.
You can have constraints on. they can be reliable, all those
things we've talked about. So to me, slightly, there's a slight tension between high level
abstraction and efficiency.
That's a good question. I could probably have a year's course just trying to answer it.
Yes, there's a tension between efficiency and abstraction,
but you also get the interesting situation that you get the best efficiency out of the best abstraction.
And my main tool for efficiency for performance actually is abstraction.
So let's go back to how C++ got there. You said it was optitory in the programming language. I actually never said that.
It's always quoted, but I never did. I said C++ supports optitory in programming,
but it's nine other techniques. And that's important because I think
that the best solution to most complex interesting problems
require ideas and techniques from things
that have been called object-oriented data abstraction,
function, or traditional C-style code, all of the above.
And so when I was designing C++, I soon realized I couldn't just add features.
If you just add what looks pretty or what people ask for or what you think is good, one by one, you're not going to get a coherent whole.
What you need is a set of guidelines that, that, that, that guys your decisions should this feature be in or should this feature be modified before it can go in and such.
And there's a, in the book I wrote about that,
that sign evolution of C++ is a whole bunch of rules like that.
Most of them are not language technical.
They are things like, don't violate static type system
because I like static type system for the obvious reason that I like
things to be reliable on reasonable amounts of hardware. But one of these rules is the serial
overhead principle. They will kind of put the serial overhead principle. It basically says that
principle. It basically says that if you have an abstraction, it should not cost anything compared to write the equivalent code at a lower level.
So if I have say a matrix multiply, it should be written in such a way that you could not drop to the sea level
of abstraction and use arrays and pointers and such and run faster. And so people have written
such matrix multiplications and they've actually gotten code that ran faster and 4-trend because once you had the right
abstraction, you can eliminate you can eliminate tempers and you can do loop fusion and other
good stuff like that.
That's quite hard to do by hand and in a lower level language.
And there's some really nice examples of that. And the key here is that that matrix multiplication, the matrix
abstraction, allows you to write code that's simple and easy. You can do that in any language.
What we see plus plus has the features so that you can also have this thing run faster than
if you hand coded it. Now people have given that lecture many times, I and others, and a
very common question after the talk where you have demonstrated that you're going to
perform Fortran for dense matrix multiplication, people come up and say, yeah, but that's C++.
If I rewrote your code and see how much faster would it run. The answer is much slower. This happened the first time
actually back in the ages with a friend of mine called Dogmatic Roy who demonstrated exactly
this effect. And so the principle is you should give programmers the tools so that the abstractions can follow the zero-way principle.
Furthermore, when you put in a language feature in C++ or a standard library feature,
you try to meet this. It doesn't mean it's absolutely optimal, but it means if you hand-code it
with the usual facilities in the language in C++ in C,
you should not be able to better it.
Usually you can do better if you use embedded
a simpler machine code for some of the details
to utilize part of a computer
that the compiler doesn't know about.
But you should get to that point
before you beat the abstraction.
So that's a beautiful idea to reach for. And we meet it quite often.
So where is the magic of that coming from? There's some of it is the compilation process.
So the implementation is supposed. Some of it is the design of the feature itself, the guidelines. So I've recently
and often talked to Chris Latner, so clang. What just out of curiosity is your relationship
in general with the different implementations of C++ as you think about you and committee
and other people in C++. Think about the design of new features or design of previous features
In trying to reach the ideal of zero overhead
Well, does the magic come from the design the guidelines or from the implementations. And, and not all.
You go for programming technique,
program language features, and implementation techniques.
You need all three.
And how can you think about all three at the same time?
It takes some experience, takes some practice,
and sometimes you get it wrong, but after a while you sort of get it right.
I don't write compilers anymore, but Brian Curnian pointed out that one of the reasons C++ succeeded was some of the craftsmanship I put into the early compilers. And of course I did the
languages sign, of course I wrote a fair amount of code using this kind of stuff. And I think
most of the successes involves progress in all three areas together. A small group of people
can do that. Two, three people can work together
to do something like that. It's ideal if it's one person that has all the skills necessary,
but nobody has all the skills necessary in all the fields where C++ is used. So if you
want to approach my ideal in say concurrent programming. You need to know about algorithms of current
programming. You need to know the the trigger of lock free programming. You need to know something
about the compiler techniques. And then you have to know some of the program areas, sorry,
the application areas where this is, like some forms of graphics or some forms of what are called a web-serving
kind of stuff.
And that's very hard to get into a single head, but small groups can do it too.
So is there differences in your view, not saying which is better or so on, but difference in the different implementations of C++.
Why are there several sort of maybe naive questions for me?
GCC claims.
This is a very reasonable question.
When I design C++,
most languages have multiple implementations. Because if you run on an IBM, if you run on a Sun, if you run on Motorola,
there was just many, many companies in the each have their own compilation structure,
and they're old compilers.
It was just fairly common that there was many of them.
And I wrote C-front assuming that other people would write compilers with C++ if successful.
And furthermore, I wanted to utilize all the backend infrastructures that were available.
I soon realized that my users were using 25 different linkers.
I couldn't write my own linker.
Yes, I could, but I couldn't write 25 linkers
and also get any work done on the language.
And so it came from a world where there was many linkers,
many optimizers, many compiler frontends,
not to start, but many operating systems.
The whole world was not an 86 and Linux box or something,
whatever is the standard today,
in the old days they set a back.
So basically, I assumed there would be lots of compilers. It was not a decision
that there should be many compilers. It was just the fact that's the way the world is.
And yes, many compilers emerged. And today there's at least four front-ends, Clang, GCC, Microsoft, and EDG.
It is the sign group.
They supply a lot of the independent organizations and the embedded systems industry.
And there's lots and lots of back-ends.
We have to think about how many dozen back-ends there are.
Because different machines have different things, especially in the embedded world,
the machines are very different. The architectures are very different.
And so having a single implementation was never an option.
Now, I also happen to dislike monocultures.
Monocultures, they are dangerous.
Because whoever owns the monoculture can go stale
and there's no competition
and there's no incentive to innovate.
There's a lot of incentive to put barriers
in the way of change, because hey, we own the world
and it's a very comfortable world for us
and who are you to mess with that?
So I really am very happy that there's four front ends
for C++, Clang's great, but GCC was great, but then it got somewhat stale. Clang
came along and GCC is much better now. Competition. My first off is much better now. So at least At least a low number of front end puts a lot of pressure on standards compliance and
also on performance and error messages, and compile time speed, all this good stuff that
we want.
Do you think crazy question, there might come along, do you hope there might come along implementation of C++ written given all its history
written from scratch. So written today from scratch.
Well, playing and the LLVM is more or less written from scratch.
But there's been C++ 11, 14, 17, 20, you know, there's been a lot of
things. Sooner or later, somebody is going to try again. There has been attempts to write
new C++ compilers and some of them has been used and some of them has been absorbed into others
and so on. Yeah, it'll happen. So what are the key features of C++?
And let's use that as a way to sort of talk about
the evolution of C++, the new feature.
So at the highest level, what are the features that
were there in the beginning, and what features got added?
Let's first get an A in place.
C++ is for people who want to use hardware really well and then manage the complexity of
doing that through abstraction.
And so the first facility you have is a way of manipulating the machine at a fairly low level.
That looks very much like sea. It has loops, it has variables, it has pointers,
like machine addresses, it can access memory directly, it can allocate stuff in the absolute minimum of space needed on the machine.
There's a machine facing part of C++ which is roughly equivalent to C. I said C++ could
beat C and it can. It doesn't mean I dislike C. If I dislike C, I wouldn't have built on
it. Furthermore, after Dennis Ritchie,
I'm probably the major contributor to modern C.
Well, I had lunch with Dennis most days for 16 years,
and we never had a harsh word between us.
So these C versus C++ fights are for people who don't quite understand what's going on.
Then the other part is the abstraction. And there the key is the class, which is a user defined type.
And my idea for the class is that you should be able to build a type that's just like the built-in types in the way you use them, in the way you declare
them, in the way you get the memory, and you can do just as well. So, in C++ as an int, as an C,
you should be able to build an abstraction, a class, which we can call capital int,
abstraction, a class, which we can call capital int, that you can use exactly like an integer and run just as fast as an integer.
There's the idea right there.
And of course, you probably don't want to use the int itself, but it has happened.
People have wanted integers that were range checked so you couldn't overflow and such. Especially for very safe, critical applications like the fuel injection for a marine diesel engine
for the largest ships. This is a real example, by the way. This has been done. They built themselves
an integer that was just like integer except that it couldn't overflow if there was no overflow you went into the error handling
And then you built more interesting types you you can build a matrix
Which you need to do graphics or you could build a gnome for
For a video game and all of these are classes and they appear just like the built-in types.
Exactly.
In terms of efficiency and so on. So what else is there?
And flexibility.
So, I don't know, for people who are not familiar with object-oriented programming,
there's inheritance. There's a hierarchy of classes. You can, just like you said,
create a generic vehicle that can turn left.
So what people found was that you don't actually know how do I say this. A lot of types are related.
That is, the vehicles, all vehicles are related. Bicycles, cars, fire engines, tanks.
They have some things in common and some things that differ.
And you would like to have the common things common and having the differences specific.
And when you didn't want to know about the differences, like just turn left.
You don't have to worry about it. That's how you get the traditional optutorian
program in coming out of Simula adopted by Small Talk and C++ and all the other languages.
The other kind of obvious similarity between types comes when you have something like a vector.
A fortune gave us the vector as called a ray of doubles.
But the minute you have a vector of doubles,
you want the vector of double precision doubles
and for short doubles, for graphics,
and why should you not have a vector of integers while you are added or vector of vectors
and a vector of vectors of chess pieces. Now we have a board. Right. So this is, you express
the commonality as the idea of a vector and the variations come through
parameterization.
And so here we get the two fundamental ways of abstracting
of having similarities of types in C++.
There's the inheritance and there's a parameterization.
There's the object-oriented programming
and there's the generic programming.
With templates for the generic programming.
So you've presented it very nicely,
but now you have to make all that happen
and make it efficient.
So generic programming with templates,
there's all kinds of magic going on,
especially recently, that you can help catch up on, but it feels to me like you can do way more than what you just said.
What templates? You can start doing this kind of meta programming, this kind of...
You can do meta programming also. I didn't go there in that explanation.
We're trying to be very basics, but go back on to the implementation.
If you couldn't implement this efficiently, We're trying to be very basic, but go back on to the implementation.
If you couldn't implement this efficiently, if you couldn't use it so that it became efficient,
it has no place in C++ because it will violate the zero or head principle.
So when I had to get up to your programming inheritance, I took the idea of virtual functions from
Simula. Virtual functions is a similar term, class is a similar term. If you ever
use those words, say thanks to Christian Newgo and all your handdaal. And I did
the simplest implementation I knew of, which was basically a jump table.
So you get the virtual function table,
the function goes in,
do it in a direction through a table and get the right function.
That's how you pick the right thing there.
And I thought that was trivial.
It's close to optimal.
It's endless obvious.
It turned out the C-mula had a more complicated way
of doing it, therefore slower.
And it turns out that most languages have something
that's a little bit more complicated,
sometimes more flexible, but you pay for it.
And one of the strengths of C++ was that you could
actually do this object-oriented stuff
and your overhead
compared to ordinary functions, there's no interactions, it's not of in 5, 10, 25% just
the core, it's down there, it's not 2. And that means you can afford to use it. Furthermore,
in C++ you have the distinction
between a virtual function and an un-virtual function.
If you don't want any overhead,
if you don't need the interaction that
gives you the flexibility and object
during the programming, just don't ask for it.
So the idea is that you only use virtual functions
if you actually need the flexibility. So it's not zero overhead, but it's zero overhead compared to any other way of achieving the flexibility.
Now, or to parameterization. looks at the template, say the vector, and it looks at the parameter, and then combines
the two and generates a piece of code that is exactly as if you have written a vector
of that specific type.
So that's the minimal overhead.
If you have many template
parameters, you can actually combine code that the compiler couldn't usually see
at the same time. And therefore get code that is faster than if you had
handwritten the stuff on a very, very clever. So the thing is, parameterized code,
the compiler fills stuff in during the compilation process,
not during runtime.
That's right.
And furthermore, it gives all the information it's gotten,
which is the template, the parameter,
and the context of use.
It combines the three and generates good code.
But it can generate, now it's a little outside of what I'm even comfortable thinking about,
but it can generate a lot of code. Yes. And how do you, I remember being both amazed at the power of that idea and how ugly the debugging worked.
Yes, debugging can be truly horrid. Come back to this because I have a solution.
Anyway, the debugging was ugly. The code generated by C++ has always been ugly because there's these inherent optimizations.
A modern C++ compiler has run-down, middle, and back end optimizations.
Even CFront back in 83 had front-end and back end optimizations.
I actually took the code, generated an internal representation,
munched that representation to generate good code.
So people say it's not a compiler, it generates C.
The reason it generated C was I wanted to use the C's code
generators that was really good at back end optimizations.
But I needed front end optimizations, and therefore the C I generated was optimized C.
The way a really good handcrafted optimizer human could generate it and it was not meant for humans.
It was the output of a program and it's much worse today.
And with templates it gets much worse today. And with templates, it gets much worse still. So it's hard to combine
simple debugging with the optimal code because the idea is to drag in information from different
parts of the code to generate good code, machine code. And that's not readable. So what people often do for debugging
is they turn the optimizer off. And so you get code that when you when when something in your
source code looks like a function core, it is a function core. When the optimizer is turned on, it may disappear.
The function core, it may inline.
And so one of the things you can do
is you can actually get code
that is smaller than the function core
because you eliminate the function preamberal
and return and there's just the operation there. One of the
key things when I did templates was I wanted to make sure that if you have a say a sort algorithm
and you give it a sorting criteria. If that sorting criteria is simply comparing things with less than, the code
generated should be the less than, not an indirect function call to a comparison object,
which is what it is in the source code. But we really want down to the single instruction. But anyway, turn off the optimizer
and you can debug the first level of debugging
can be done and I always do without the optimization on.
Because then I can see what's going on.
And then there's this idea of concepts
that put some...
Now I've never even... I don't know if it was ever available
in any form, but it puts some constraints on the stuff you can parameterize essentially.
Let me try and explain. Yes. So yes, it wasn't there 10 years ago. We have had versions of it that actually work for the last four, five years.
It was a design by Gabi does raise Trussorten and me.
We were professors and postdocs in Texas at the time. And the implementation by interest
garden has been available for that time. And it is part of C++20.
And the standard library that uses it. So this is becoming really very real. It's available in Clang and GCC, GCC for a couple of years.
And I believe Microsoft is soon going to do it.
Expect all of C++20 to be available.
So in all the major compilers in 20.
But this kind of stuff is available now. I'm just saying that because otherwise people
might think I was talking about science fiction. And so what I'm going to say is concrete,
you can write it today. And there's production uses of it. So the basic idea is that when you have a generic component like a sort function, the sort function will
require at least two parameters, one at data structure with a given type and a comparison
criteria. And these things are related, but obviously you can't compare things if you don't know
what the type of things you compare.
And so you want to be able to say, I'm going to sort something and it is to be sortable.
What does it mean to be sortable?
You look it up in the standard.
It has to have, it has to be a sequence with a beginner and an end. There has to be random access to that sequence and there has to be
the element types has to be comparable
by the less than operator it can operate on it. Yes, last logical. Basically, what
concepts are their compile time predicates're predicates you can ask.
Are you a sequence?
Yes, I have a beginning end.
Are you a random exit sequence?
Yes, I have a subscripting and plus.
Is your element type something that has a lesson?
Yes, I have a lesson.
And so basically that's the system. And so instead of saying,
I will take a parameter of any type, it'll say I'll take something that's sortable.
And it's well defined. And so you say, okay, you can sort of less than, I don't want less than,
I want greater than or something I invent. So you have two parameters, the sortable thing and the
compassion criteria.
And the compassion criteria will say, well, I can,
you can write it saying it should
operate on the element type and it has the compassion
operations.
So that's simply the fundamental thing. It's compile time predicates.
Do you have the properties I need? So it specifies the requirements of the code on the parameters
that it gets. It's very similar to types, actually. But operating in the space of concepts.
but operating in the space of concepts. Concepts. The word concept was used by Alex Stefanoff, who is sort of the father of generic programming in the context of C++.
There's other places that use that word, but the way we call generic programming is Alex's.
And he called them concepts because he said they're the
sort of the fundamental concepts of an area.
So they should be called concepts.
And we've had concepts all the time.
If you look at the K&R book about C,
C has arachmetic types and it has integral types.
It says so in the book. And then it lists what they are and they have certain
properties. The difference today is that we can actually write a concept that will ask a type,
are you an integral type? Do you have the properties necessary to be an integral type. Do we have plus minus divide and such?
So maybe the story of concepts, because I thought it might be part of C++11,
C0X, whatever it was at the time. What was the, why didn't it, what, like what,
we'll talk a little bit about this fascinating
process of standards, because I think it's really interesting for people, it's interesting
for me, but why did it take so long, what shapes the idea of concepts take, what were the
challenges?
Back in 87, what were there about?
1987.
1987, thereabouts.
When I was designing templates, obviously, I wanted to express the notion of what is required
by a template of its arguments.
And so I looked at this.
And basically, for templates, I wanted three properties.
I wanted to be very flexible.
It had to be able to express things I couldn't imagine.
Because I know I can't imagine everything
and I've been suffering from languages that I tried to constrain you
to only do what the designer thought good.
Didn't want to do that.
Secondly, it had to run faster,
as fast or faster than hand-written code.
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.
And thirdly, I wanted to be able to express
the constraints of the arguments,
have proper type checking of the interfaces.
And neither I nor anybody else at the time
knew how to get all three.
And I thought, for C++, I must have the tool first.
Otherwise, it's not C++.
And it bothered me for an hour, a couple of decades
that I couldn't solve the third one.
I mean, I was the one that put
function argument type checking into C.
I know the value of good interfaces.
I didn't invent that idea. It's
very common, but I did it. And I wanted to do the same for templates of course, and I could. So it
bothered me. Then we tried again, 2000 of two, 2003, Kabbiter's raison d' reason I started analyzing the problem, explained possible solutions. It was not a
complete design. A group in University of Indiana, an old friend of mine, they started a project at at Indiana and we thought we could get a good system of concepts in another two or three
years. That would have made C++ 11 to C++ 06 or 07. Well, it turned out that I think we got a lot of the fundamental ideas wrong.
They were too conventional. They didn't quite fit C++ in my opinion. Didn't serve implicit
conversions very well. It didn't serve mixed type arithmetic, mixed type computations very well. A lot of stuff came out of the functional
community and it that community didn't deal with multiple types in the same way as C++ does,
in the same way as C++ does had more constraints on what you could express and didn't have the draconian performance requirements. And basically we tried, we tried
very hard, we had some successes, but it just in the end wasn't, didn't compile fast enough, was too hard to use, and didn't run fast enough
unless you had optimizers that was beyond the state of the art.
They still are.
So we had to do something else.
Basically, it was the idea that a set of parameters has defined a set of operations and you go
through an interaction table just like for virtual functions.
Then you try to optimize the interaction away to get performance.
And we just couldn't do all of that.
But get back to the standardization. We are standardizing C++
under ISO rules, which are very open process. People come in, there's no requirements for
educational experience. So you've started to develop C++. And there's a whole, what was the first standard established? What is that like the
ISO standard? Is there a committee that you're referring to? There's a group of people?
What was that like? How often do you meet? What's the discussion? I'll try and explain
that. So sometime in early 1989, two people won from IBM, one from HP, turned up in my office and told
me I would like to standardize C++.
This was a new idea to me and I pointed out that it wasn't finished yet and it wasn't
ready for formal standardization
and such.
And they say, no, Bihanna, you haven't gotten it.
You really want to do this.
Our organization's depend on C++.
We cannot depend on something that's owned by another corporation that might be a competitor.
Of course, we could rely on you, but you might
get run over by a bus. We really need to get this out new. It has to be standardized under
former rules, and we are going to standardize it under ISO rules. And you really want to be part of it because
basically otherwise we'll do it ourselves. And we know you can do it better. So through
a combination of arm twisting and flattery, care got started. So in late, in late H9, there was a meeting in DC at the,
actually, no, it was not ISO then it was NC, the American national standard were doing.
We met there. We were lectured on the rules of how to do an anti-standard.
There was about 25 of us there, which apparently was a new record for that kind of meeting.
And some of the old C guys that has been standing right in C was there, so we got some expertise in.
So the way this works is that it's an open process. Anybody can sign up if they pay the minimum fee,
which is about $1,000, they're less than a little bit more now.
And I think it's $180.
It's not going to kill you.
And we have three meetings a year.
This is fairly standard. We tried to meetings a year, this is fairly standard.
We tried to meetings a year for a couple of years
that didn't work too well.
So three meetings a year and you meet,
and you have technical discussions
and then you bring proposals forward for votes. The votes are done, one person per
one vote per
organization. So you can't have say IBM come in with 10 people and dominate things that's not allowed.
And these organizations that extend to the UC++. Yes. Or individuals.
Or individuals.
I mean, it's a bunch of people in the room deciding the design of a language based on
which a lot of the world's systems run.
Right.
Well, I think most people would agree it's better than if I decided it, or it better
than if a single organization like than if I decided it or better than if a single
organization like H&T decides it. I don't know if everyone agrees to that by
the way. bureaucracies have their critics too. Yes they they're that look
standardization is not pleasant it's it's it's it's horrifying. It's like
democracy. But we exactly as church, democracy is the worst way except for the others, right?
And it's, I would say, the same with former standardization.
But anyway, so we meet and we have these votes and that determines what the standard is.
A couple of years later, we extended this,
so it became worldwide.
We have standard organizations that are active in currently,
15 to 20 countries, and another 15 to 20
are sort of looking and voting based on the rest of the work on it.
And we meet three times a year.
Next week I'll be in Cologne, Germany, spending a week doing standardization.
And we will vote out the committee draft of C++ 20, which goes to the National Standards Committee's for
comments and requests for changes and improvements, then we do that.
And there's a second set of votes where hopefully everybody votes in favor.
This has happened several times.
The first time we finished, we started in the first technical meeting was in 1990.
The last was in 1998.
We voted it out.
That was the standard that people used till 11 or a little bit past 11.
And it was an international standard.
All the countries voted in favor.
It took longer with 11, I know, mentioned why, but all the
nations voted in favor. And we work on the basis of consensus, that is, we do not want
something that passes 60-40, because then we're good in getting a dialects and opponents and people
Complain too much. They all complain too much, but basically it has no real effect. The standards has been obeyed
They have been working to make it
Easier to use many compilers many computers. No, all of that kind of stuff
And so the first, the traditional with ISO
standards to take 10 years, we did the first one and eight brilliant. And we thought we
were going to do the next one and six because now we are good at it. Right. It took 13.
Yeah, it was named OX. It was named O oh X hoping that you would at least get it within the single within the arts the single
I thought we would get I thought would get six seven or eight the confidence of youth. Yeah, it's right
Well, the point is that this was sort of like a second
System effect that is we now knew how to do it and so we're going to do it much
better and we've got more ambitious and it took longer. Furthermore there is
this tendency because it's a 10 year cycle or age doesn't matter just before
you're about to ship somebody has a bright idea. And so we really, really
must get that in. We did that successfully with the STL. We got the standard library
that gives us all the STL stuff. That I basically, I think it saved C++. It was beautiful. Yeah. And then people tried it with other things and it didn't work so well. They got things in,
but it wasn't as dramatic and it took longer and longer and longer. So after C++ 11,
which was a huge improvement and what basically what most people are using today, we decided never again.
And so how do you avoid those slips? And the answer is that you ship more often, so that
if you have a slip on a 10-year cycle, by the time you know it's a slip, there's 11 years till you get it.
Now with a three-year cycle, there is about three, four years till you get it. Like the delay
between feature-freeze and shipping. So you always get one or two years more. And so we shipped
So you always get one or two years more. And so we shipped 14 on time, we shipped 17 on time,
and we will ship 20 on time.
It'll happen.
And furthermore, this gives a predictability
that allows the implementers, the compile implementers,
the library implementers, they have a target and
they deliver on it. 11 took two years for most compilers were good enough. 14 most compilers were
actually getting pretty good in 14, 17 everybody shipped in 17. Well, we are going to have
At least almost everybody ship almost everything in 20 and I know this because they're shipping in 19
Predictedly this is good delivery on time is good and so yeah, that's great. That's how it works
There's a lot of features that came in in C++ 11. There's a lot of features at the birth of C++.
They were amazing and ideas with concepts in 2020.
What to you is the most,
just to you personally, beautiful or just you sit back
and think, wow, that's just nice and clean feature of C++.
I have written two papers for the history of programming languages conference, which basically
asked me such questions.
And I'm writing a third one which I will deliver
at the history of programming languages conference in London next year. So I've been thinking about
that and there is one clear answer, constructors and destructors. The way a constructor can establish
the environment for the use of the type for an object,
and the destructor that cleans up any messes at the end of it.
That is the key to C++.
That's why we don't have to use garbage connection.
That's how we can get predictable performance.
That's how you can get the minimal overhead
in many, many cases and have really clean types.
It's the idea of constructor destructor pairs.
Sometimes it comes out under the name R-I-I-I resource acquisition is initialization,
which is the idea that you grab resources and the constructor and release them in destructor.
It's also the best example of why I shouldn't be in advertising. I get the best idea and I call it resource acquisition is initialization.
Not the greatest naming I've ever heard. So, it's types, abstraction of types.
You said, I want to create my own types.
So, types is an essential part of C++.
And making them efficient is the key part.
And to you, this is almost getting philosophical,
but the construction and the destruction, the
creation of an instance of a type and the freeing of resources from that instance of a
type is what defines the object is a, that's almost like birth and death as what defines human
life.
Yeah, that's right. By the way, philosophy is important.
You can't do good languages, sign without philosophy, because what you are
determining is what people can express and how.
This is very important. By the way, constructors,
destructors came into C++ in 17. In about the second week of my work with what was then called C++, it is a fundamental
idea.
Next comes the fact that you need to control copying.
Because once you control, as you said, birth and death, you have to control taking copies,
which is another way of creating an object.
And finally, you have to be able to move things around.
So you get the move operations.
And that's the set of key operations you can define on a C++ type.
And so to you, those things are just a beautiful part of C++ that is at the core of it all.
Yes.
You mentioned that you hope there will be one unified set of guidelines in the future for how to construct a programming language.
So perhaps not one programming language, but a unification of how we build programming languages.
If you remember, such statements.
I have some trouble remembering it,
but I know the origin of that idea.
So maybe you can talk about,
sort of C++ has been improving.
There's been a lot of programming language.
Do you, where does the ARCA history taking us?
Do you hope that there is a unification
about the languages with which we communicate
in the digital space? Well, I think that languages should be designed not by
clobbering language features together and doing slightly different versions of somebody else's ideas, but through the creation of a set of principles, rules of thumbs, whatever you call them,
I made them for C++ and we're trying to teach people in the standards committee about these rules,
because a lot of people come in and say, I've got a great idea. Let's put it in the language. And then you have to ask, why
does it fit in the language? Why does it fit in this language? It may fit in another language
and not here, or it may fit here, not the other language. So you have to work from a set of
principles and you have to develop that set of principles. And one example that I sometimes remember is I was sitting down with some of the designers
of common list.
And we were talking about languages and language features and obviously we didn't agree about anything
because well this was not C++ and I subversa, it's too many parentheses, but
suddenly we started making progress. I said I had this problem and I developed it
according to these ideas and they said? We had that problem, different problem,
and we developed it with the same kind of principles.
And so we worked through large chunks of C++
and large chunks of common list
and figured out we actually had similar sets
of principles of how to do it. But the constraints on our
designs were very different. And the aims for the usage was very different. But
there was commonality in the way you reason about language features and the
fundamental principles you were trying to do. So do you think that's possible to her?
So just like there is perhaps a unified theory
of physics, of the fundamental forces of physics,
that I'm sure there is commonalities among the languages,
but there's also people involved that help drive
the development of these languages.
Do you have a hope or an optimism that there will be a unification?
If you think about physics in Einstein, towards a simplified language, do you think that's
possible?
Let's remember sort of modern physics, I think think started with Galileo in the 1300s.
So they have had 700 years to get going.
Modern computing started in about 49.
We've got 70 years.
They have 10 times. Furthermore, they are not as bothered with people using physics.
The way we are worried about programming is done by humans.
So each have problems and constraints.
The others have, but we are very immature compared to physics. So I would look at sort of the philosophical level and look for
fundamental principles like you don't leak resources, you shouldn't. You don't take errors at
runtime that you don't need to. You don't violate some kind of type system, there's many kind
of type systems, but when you have one, you don't break it, etc., etc., there will be
quite a few, and it will not be the same for all languages, but I think if we step back
at some kind of philosophical level, we would be able to agree on
sets of principles that apply to sets of problem areas. And within an area of use,
like in C++ case, what used to be called systems programming, the area between the hardware and the fluffier parts
of the system, you might very well see a convergence.
So these days, you see Rust having adopted RAII,
and sometimes accuses me for having borrowed it 20 years
before they discovered it.
But it's, we're seeing some kind of
conversion, convergence here instead of relying on garbage collection all the time. The garbage collection
languages are doing things like the disposed patterns and such that imitates some of the construction, destruction stuff, and they're trying not to use the garbage collection all the time.
Things like that, so there's conversion.
But I think we have to step back to the philosophical level at the Korean principles, and then we'll see some conversions, convergences, and it will be application domain specific.
So a crazy question, but I work a lot with machine learning with deep learning.
I'm not sure if you touched that world much, but you can think of programming as a thing that takes some input.
A programming is the task of creating a program,
and a program takes some input and produces some output.
So machine learning systems train on data
in order to be able to take an input and produce output.
But they're messy fuzzy things,
much like we as children grow up,
we take some input, we make some output, like we as children grow up,
we take some input, we make some output, but we're noisy, we mess up a lot,
we're definitely not reliable,
biological system or a giant mess.
So there's a sense in which machine learning
is a kind of way of programming, but just fuzzy.
It's very, very, very different than C++. Because C++ is a, like,
it's just like you said, it's extremely reliable, it's efficient, you can measure, you can
test in a bunch of different ways with biological systems or machine learning systems, you can't say much except sort of empirically saying that 99.8%
of the time it seems to work. What do you think about this fuzzy kind of programming? Do you
even see it as programming? Is it solely totally another kind of world? I think it's a different kind of world and it is fuzzy and in my domain, I don't like
fuzziness.
That is, people say things like they want everybody to be able to program.
But I don't want everybody to program my aeroplane controls or the car controls.
I want that to be done by engineers. my airplane controls or the car controls.
I want that to be done by engineers.
I want that to be done with people
that are specifically educated and trained
for doing building things,
and it is not for everybody.
Similarly, a language like C++ is not for everybody.
It is generated to be a sharp and effective tool
for professionals basically and definitely for people who aim at some kind of precision.
You don't have people doing calculations without understanding math, right? Counting on your fingers not going to cut it
if you want to fly to the move.
And so there are areas where
and 84% accuracy rate, 16% false positive rate,
is perfectly acceptable and where people will probably get more than 70.
You said 98%.
What I have seen is more like 84 and by really a lot of blood sweat and tears, you can get
up to 92 and a half.
So this is fine.
If it is say pre-screening stuff before the human look at it.
It is not good enough for life threatening situations.
And so there's lots of areas where the fossaness is perfectly acceptable and good and better
than humans, cheaper than humans, but it's not the kind of engineering stuff
I'm mostly interested in.
I worry a bit about machine learning
in the context of cars.
You know much more about this than I do, I worry too.
But I'm sort of an amateur here.
I've read some of the papers, but I've not ever done it. And the idea
that scares me the most is the one I have heard, and I don't know how common it is, that
you have this AI system, machine learning, all of these trained neural nets. And when there's something
that's too complicated, they ask the human for help. But the human is reading a book or a sleep.
And he has 30 seconds or three seconds to figure out what the problem was that the AI system couldn't handle and do the right thing.
This is scary.
I mean, how do you do the cotto wall between the machine and the human?
It's very, very difficult.
And for the designer of one of the most reliable, efficient, and powerful programming languages, C++,
I can understand why that world is actually unappealing.
It is for most engineers.
To me, it's extremely appealing because we don't know how to get that interaction right,
but I think it's possible, but it's very, very hard.
It is.
And you know, it's stating a problem.
Not that.
That is impossible.
I mean, I would much rather never rely on the human.
If you're driving a nuclear reactor,
if you're an autonomous vehicle,
it's much better to design systems written in C++
that never ask human for help.
Let's just get one fact in.
Yeah.
All of this AI service on top of us.
Yes, yes.
So that's one reason I have to keep it, whether I
out what's going on in that field.
But I will never become an expert in that area.
But it's a good example of how you separate different areas
of applications. And you have to have different
tools, different principles, and then they interact.
No major system today is written in one language and there are good reasons for that.
When you look back at your life work, what is a moment? What is a event creation that you're really
proud of? They say damn, I did pretty good there. Is it as obvious as the creation of C++?
And so obvious, I've spent a lot of time with C++ and there's a combination of few good ideas, a lot of hard work and a
bit of luck.
And I try to get away from it a few times, but I get dragged in again partly because I'm
most effective in this area and partly because what I do has much more impact if I do it
in the context of C++.
I have four and a half million people that pick it up tomorrow,
if I get something right.
If I did it in another field, I would have to start learning,
then I have to build it, and then we'll see if anybody wants to use it.
One of the things that has kept me going for all of these years
is one, the good things that people
do with it and the interesting things they do with it. And also, I get to see a lot of
interesting stuff and talk to a lot of interesting people. I mean, if it has just been statements on paper on a screen, I don't think I could have
kept going.
But I get to see the telescopes up on Monica and I actually went and see how Ford built
cars and got to JPL and see how they do the Mars rollers.
There's so much cool stuff going on and most of the cool stuff is done by pretty nice people and sometimes in very nice places
Cambridge Sophia and C. Bulless
C. Lincoln Valley. Yeah, it's
there's more to it than just code, but code is central.
There's more choice than just code, but code is central. On top of the code are the people in very nice places.
Well, I think I speak for millions of people.
We are in saying thank you for creating this language
that so many systems are built on top of that.
That make a better world.
So thank you, and thank you for talking today.
Yeah, thanks.
And we'll make it even better.
Good.
Thank you.