Algorithms + Data Structures = Programs - Episode 117: OOP, C++ Containers, APIs, EOP & More with Zach Laine!
Episode Date: February 17, 2023In this episode, Conor and Bryce talk to Zach Laine!Link to Episode 117 on WebsiteDiscuss this episode, leave a comment, or ask a question (on GitHub)TwitterADSP: The PodcastConor HoekstraBryce Adelst...ein LelbachAbout the GuestZach Laine has been using C++ in industry for 15 years, focusing on data visualization, numeric computing, games, generic programming, and good library design. He finds the process of writing bio blurbs to be a little uncomfortable.Show NotesDate Recorded: 2023-02-16Date Released: 2023-02-17UT AustinObject Oriented ProgrammingC++ virtualDynamic and Static PolymorphismAd Hoc PolymorphismParametric PolymorphismRank PolymorphismElements of Programming (Free PDF)The Structure and Interpretation of Computer ProgramsC++23 std::flat_mapC++17 std::string_viewC++20 std::spanC++20 std::basic_string::starts_withC++20 std::basic_string::ends_withC++20 std::basic_string::containsIntro Song InfoMiss You by Sarah Jansen https://soundcloud.com/sarahjansenmusicCreative Commons — Attribution 3.0 Unported — CC BY 3.0Free Download / Stream: http://bit.ly/l-miss-youMusic promoted by Audio Library https://youtu.be/iYYxnasvfx8
Transcript
Discussion (0)
All right. All right. Bryce, Bryce fancy. Everyone knows Bryce fancy. All right. The guy with a sweatband and a Heather Gray t-shirt wants to tell us what's fancy and what's not. All right, Bryce. We got it.
I might make that the cold open on every single one. welcome to adsp the podcast episode 117 recorded on february 16th 2023 my name is connor and today
with my co-host bryce we talked to zach lane about a plethora of topics including object-oriented
programming c++ containers apis the elements of programming, and so much more.
This is part one of probably a four or five-part interview series.
All right, well, we should introduce Zach.
Works at Cadence Systems, senior principal engineer, I believe.
More importantly, or I don't know, maybe it's more important, maybe it's not.
He's a member of the ISO C++ committee, author of multiple Boost libraries.
We've met before multiple times.
And I was just at your LinkedIn profile.
I had no, do you live in Austin?
Yeah.
Man, that's a missed opportunity.
I was just in Austin.
You were just in Austin?
In January.
Yeah, for my favorite race of all the races I've ever raced, which is like probably, I don't know, 30, 40, 50.
The 3M Austin Half Marathon.
It happened on January 22nd, and it's a great race because it's mostly downhill.
Those are my favorite kind of races.
I always feel I perform my best when I'm running downhill.
And yeah, I was there for a few days.
Austin's got to be, it might be my number one favorite American city.
Really?
Definitely better than New York.
Oh, okay.
Well, now we've got a problem here.
It's got that downtown vibe, but also like five minutes from downtown.
Yeah, it's better than Nework if you want to get like
hit by a car in austin i think you're thinking of houston yeah i know he's a get by a car in
houston there's a thing when you cross the street in houston people speed up when they see you
because they're like you're in my lane get on my lane now i'm i'm sure i'm sure that zach has never
heard but has never heard of this race or run this race because when was the last time that you ran?
2000.
I mean, at one point I ran a five minute mile, but that was like a very long time ago.
That's fast.
Yeah.
No, I didn't want to.
Like they made me.
Was it like the police that made you?
It was that or it was a five-minute mile or five years in the clink.
So I was like – I was on my toes.
No, it was – I was in the army 20 years ago.
Oh, wow.
25, yeah.
That's super fast.
Yeah, we're running formation and you don't want to fall out.
And I remember literally yelling for the back of formation,
where's the fire? Because I'm like, why are we running so fast? And then I looked at my watch,
and I was like, that was that was the mile mark. And that's five minutes was almost like 505 or something. I was like, Jesus Christ. Yeah, that's very, very fast. So so you and I and I know,
Zach, last week, we spent a bunch of time talking about you telling me about your Army past, but I don't know that I know this detail.
Did you go to college in the Army or Army then college?
No, I was in the college.
Well, so I was in college and then I kind of dropped out and I was, you know, did a bunch of stuff, including being in the Army.
So it took me 11 years to get through undergrad, like from beginning to end.
I started in 92 and I ended in 2003.
So a
lot of people like my age have been working a lot longer than I have. And then a lot of people much
younger than me have about the same seniority that I do. It's kind of an odd thing. But yeah,
that was just because like I was a really, really crap student and I didn't want to be in school.
And I enjoyed the coursework. I just didn't want to do it. I just, you know, I wanted to just
like hang out and, and talk to people and have a good time and not do anything. You know, I mean,
I mean, that is the best part of university. Yeah. I mean, that, and so that's the thing is
that I feel like it's one of those things where I was given just enough freedom to be like, Oh,
why don't I just do this all the time? And so then it turned into like my entire existence.
And so that was, that was,
you know, bad for, for like coursework and stuff. But then eventually, you know, I kind of slept in
the mud for three years and I was like, oh yeah, I like want a job job. I don't want to do this.
I don't want to do anything like this. So I became super student when I came back as the
dean list and all this stuff. So yeah, it was, it was good for me to have that as the sort of
break that had the middle
because if I just sort of, you know, worked at 7-Eleven or something, I'd probably still be
working. I saw that you also you went to UT Austin. Was that both before and after the three years
in the mud? Yeah, yeah, yeah. And, you know, I went to UT Austin because I was, you know,
from Houston, and I had one parent who lived in Austin. So I knew Austin, I knew I wanted to live
there. I liked it a lot. I had friends that from my high school that ended up there. And so I went there for like essentially social
reasons. And I just happened to be in a top five computer science department, like, like with zero
effort on my end. Like I was in the top 10 of my graduating class. And at the time that meant
you had a push button admission to any school in the UT system if you're, if you're a Texas
graduating high school student.
I literally filled out a postcard and that was it.
The fact that I
got such a good computer science education
was a complete accident, but
I'm really thankful for it. I got a really good
education there.
Were you doing computer
science before you
went into the Army? Did you know when you went to college
that's what you wanted to do?
Yeah, yeah, absolutely.
So I, well, the funny thing is, like, my entire childhood, I wanted to be a physicist.
Like, I saw these guys on Nova on, you know, on public TV, and I was like, I want to be one of those guys.
I want to be a physicist.
I was always obsessed with, like, you know, space and astrophysics and stuff like that and um you know i like read a bunch of
physics texts like in high school like just out of curiosity right um and i would read physics
papers sometimes i was like really into it and i remember um at some point um i was just messing
around with my computer and i wanted to like do a little bit of programming and all the stuff i did
was physics related um but then when i was filling out this little postcard that I
referred to before like there was a when you're in the college of natural sciences there's one
postcard there's a different one for the the college of liberal arts and so I was on the
natural sciences one there's a there's a checkbox for each of the majors right so if you get into
UT like you just pick your major you get into one of those two schools like like I said you pick the. And I was looking at the checkboxes and I was like, Oh, maybe I'll do computer science. That's literally how long I thought about it. Because look, physics, computer science, why not? And so that's why I did the major that I did. Yeah.
If you went into physics, you probably would have ended up in computer science anyways. linear algebra interface is standardized. And so a lot of those folks are mathematicians or physicists,
and they do tons of like really rigorous computer science work as part of their job.
It's just the nature of the business.
If you work in any kind of applied math,
and if you work in any kind of physics these days,
you know, your job as a programmer, like more than it's not.
Yeah, it's really sort of astonishing how over the past 30 to 40 years
in almost all scientific fields, a large chunk of the field has moved to computational work.
But even for the chunk of the field that's still wet lab work where you're still running physical experiments or something, increasingly there's a computational component to that work too because you're collecting so much data with these instruments that you have to do some post-processing of whatever actual experiments you're doing. And so it's like, like these days,
like if you're, if you're, if you're in a career path where you want to study the sciences,
you're probably going to end up having to do some programming.
Yeah. Well, so the first half of my career was at a research lab at UT called Applied Research Laboratories, ARL.
And I worked with a whole bunch of people on sonar.
And most of them were physicists who decided they didn't want to do physics anymore.
One of whom was he said the reason he did sonar instead of cosmology is because sonar is so much harder.
Because it's a crazy, crazy hard thing to do uh because
the noise propagation is is incredibly noisy i mean sound propagation is incredibly noisy and
it's like uh you might as well just call it noise propagation it's all dealing with noise uh whereas
like you can get really good signals sometimes uh in cosmology and those tend to be the areas
people focus on but um yeah it was interesting like dealing with like there was one project in particular it was just me and this physicist right so we had this common tracker
uh that we used to track signals and sonar data and with this old implementation it was really
crusty everybody's afraid to touch it and like we're going to do a fresh implementation of that
from scratch and i remember at one point like we weren't doing a lot of object-oriented programming
for this obviously it's numeric stuff and i don't really like oh anyway and um so he was he asked me at one point
what's this virtual what's virtual function what is that and i was like oh and i explained like you
know how you'd have like a bunch of different flavors of stuff and you have a switch statement
it kind of gets rid of the switch statement and it goes all the way through and there's these
problems with it and blah blah and that was a little beyond what he can understand.
So six months later, he's like, what is this virtual function?
And I did the whole thing.
I explained it to him.
We went into his office.
We've talked for it.
I explained the whole thing.
And then a third time it happened about a year later.
And I was like, Jim, I'm done.
Like, this is it.
This is the last one.
Take notes if you want to know what this is in the future or just live in ignorance.
And I remember at one point, the same kind of thing happened, but the other way around.
Like I asked about something I was kind of curious about, but it didn't stick.
And I asked him about the same thing again.
He's like, I already explained this to you, like some physics thing, right?
And it's really funny how when people are technically oriented, whatever they're oriented towards, the things that they're interested in stick in their heads really easily compared to other equally hard to understand things that are just outside of their
interest area. Right. And so when, when you sort of focus on one technical area, not another one,
even if it's an adjacent area, a lot of times, like there's, there's a real lack of understanding.
And it's not because these things are any harder to understand. So you're just not oriented towards
doing that work to understand, you know, it's like that quote, uh, the neurons that fire together,
wire together. It's like, if you already have the vocabulary in your them, you know? It's like that quote, the neurons that fire together, wire together.
It's like, if you already have the vocabulary in your head,
you know, learning something that's adjacent to that
is super easy.
But if it's in some other domain that,
sure, it's just as hard,
but you don't have the vocabulary,
you don't have the wires that can fire together.
So it's just, it's, I remember,
it's like so many things I've learned.
Like I went through a finance phase
where I wanted to be a quant.
They just have the vocabulary, the jargon that they have, like share, stock.
You get into options and stuff, derivatives, exotic.
It's just like you have to learn this whole vocabulary first.
I remember asking my parents, man, what's the difference between a stock and a share?
They didn't know.
It's such a subtle thing, but it's not difficult. It's just, you need,
you need to have the vocabulary in order to, to really grok if someone's explaining something to you. If, if every fourth word is like, I don't know what that means, then it's not going to
stick. Right. Yeah. And I think that's, that's, that's a, it's a huge problem for a software
engineering education because we have, I mean, every field has its own language, but I think that's, that's, that's a, it's a huge problem for a software engineering education because we have, I mean, every field has its own language, but I think we in particular
have a lot of jargon.
And I think that it becomes so natural to us that we don't even realize how unapproachable
it is to, to newcomers.
And the way it's taught is like, like I was, who was I just talking to this the other day,
the polymorphism, like in school, it's's just taught like when they teach polymorphism the unit in whatever engineering
201 software engineering 201 they just teach like runtime polymorphism which also is known as dynamic
polymorphism but like there are i think we i listed off like 10 different types static polymorphism
also known as compile time polymorphism ad hoc polymorphism parametric polymorphism like
rank polymorphism it just goes on and onism, parametric polymorphism, like rank polymorphism.
It just goes on and on and on.
But in school, they refer to polymorphism and it just refers to dynamic.
But there's like literally 10 different types.
And I've never seen a talk that talks about like the umbrella world.
You know, here's an umbrella term, polymorphism and all the different types.
And I remember in an interview, I got asked once, what is static polymorphism?
And then I was like, I think that's like, I think that's like templates. And they remember in an interview, I got asked once, what is static polymorphism?
And then I was like, I think that's like, I think that's like templates. And they were like, yeah.
And they're like, so why is it called static polymorphism? I was like, listen, I don't know much about templates. Like, I just started learning C++. And anyways, it's just, yeah,
the vocabulary problem is, it's a problem because even in education, like they teach
things in a very, very, I wouldn't even say it's simplified.
Like I think that's misleading to teach the word polymorphism and not start off by saying,
okay, we're going to focus on this one type, but like there are 12 different other types
that you're going to get to depending on the language you work in.
And I think that's really true, especially in the light of the fact that, you know, there
is lots of use for polymorphism in code. There's very seldom a need for dynamic polymorphism code right and so like
very often i see people do stuff that are you know the kind of intermediate programs i work with a
lot of programmers that are like that and it's not a failing of theirs is that they came from
double e and they're kind of learning on the job and so it's another it's another question of of
focus and so when when they when they see a new programming technique, they aren't like really interested in drilling down on that.
That's what they become obsessed with for a while.
They're like, oh, someone did it a different way.
I don't care, right?
I'm getting my work done this way.
That's the important part.
The way that I'm used to doing it, how can I perfect whatever direction I'm already in?
So they already know like OO type stuff.
They write lots of virtual functions even when that's not necessarily the right tool for the job.
And that's one of the things I just mentioned not liking OO, but I think that's like a really big deal in our industry that there's so many people that even now, if you look like on online courses, like introductory stuff for C++ people, there's no good learning resources for C++.
That's a different topic. But what there is out there, a lot of it's very focused on the same kind of overlap
with, I'm sure, other courses that
the same people are making for other languages.
And that includes lots of ideas from Java
and other things that sort of
co-evolved with C++
in the early days. But
those people writing those tutorials have no idea
that the sort of
cognoscente within C++
have completely moved away from that paradigm
and that's seldom used yeah except sometimes as an implementation detail of something else
um yeah it's it's really kind of it's kind of unfortunate because i think a lot of people
reach for that in fact you know the previous role i had at my current job i did a lot of like
internal training and and like there was part of this thing called the quality team the whole idea
was to like decrease the defect rate in our in our code which was kind of this thing called the quality team. The whole idea was to decrease the defect rate in our code,
which was kind of high.
Well, tragically high.
It was awful, right?
And so we were trying to get rid of crashes at customer sites
and stuff like this.
So one of the things my boss and I were talking about
when I first joined the team was he was like,
maybe we could do some internal training about this or that.
What do you think about putting together a course from first principles, like how to write code well, like, you know, good object-oriented techniques.
And I was like, well, it's funny that you say that because it's no such thing.
His head kind of exploded.
But, you know, he was great about like recognizing like new material when I would present to him, like new techniques and why they were important.
And he really took a lot of those lessons on board. And that was really cool. So he wasn't
like pushing back against that. He was just surprised by it. And that reflects like an
older mentality because when he was a day-to-day practitioner, that was kind of the way you did
things. And unfortunately, that has persisted, especially as like people that were from that
era move into management. And then people below them are trying to do something a certain way.
They're like, oh, you want to do an object oriented thing with like some big class diagram
or something.
And so that, that tends to perpetuate it.
And I'm kind of waiting for people to like, I know no one's going to read EOP, but I'm
ready for people to adapt those, those kind of, or adopt, I should say those kind of,
those kind of approaches of, you know.
And that's, that's Elements of Programming uh stephanov's uh uh book which is sort of the
it's it might not be the best book about computer science ever written but it's the best one ever
it's the it's the only book on computer science or programming that i've ever read i think we've
talked in this podcast before about how i'm not a huge fan of like wait didn't you i thought you
said that about sick p which is the structure you know what programs I I've read parts of sick p I've elements of
programming is the only programming book I've read all the way through like those are the two
that I've read from like and not just like skimmed the index of um yeah uh and uh elements of
programming is the only one that I've read I've actually read through it twice so I've read lots
of them and I really think elements of programming is the one that I've read. I've actually read through it twice. So I've read lots of them, and I really think Elements of Programming is the one that I appreciate the most.
And in fact, what I often tell people is, you know, you can get us a free PDF download these days.
Like, you don't even need to pay for it.
You don't even need to hold around a dead tree in your hands, right?
All you need to do is, like, go and download it from somewhere.
But if you can internalize the first six pages of the first chapter, that's all you need. Literally,
the first six pages. If you can internalize that, the rest of it is logical extension of that first
six pages. If you apply those first six pages to all these kinds of programming styles that are
covering the rest of the book, that's where the rest of the book comes from. And the rest of the
book is very dense and hard to get through. That first six pages is also dense and hard to get
through, but it's only six pages. So it's you know a time investment i always tell people that i don't
think i've had any takers but i mean the stuff in that first six pages is so good you know i don't
know if you guys had a similar experience of like you know when i was first starting out i would
hear about some technique and i would like be like i'm going to find an excuse to use my code
because that's interesting i'm gonna see if that works right and so you do things like kind of like
the wrong way on purpose to see how it worked.
And then you're like, ah, it works or it didn't.
And you kind of adapt, right?
So there have been many, many different styles of like things from like, you know, just texting, textual conventions like, you know, where you put hanging braces.
All these different things I've tried over the course of my career over and over again, different experiments. And the only bit of advice that I have,
once I internalized it, I literally never looked back or never changed, even when I had new data
introduced to me as those first six pages of that first chapter. I mean, they're really,
I think, unassailable. What are the key lessons to take away from?
So some of the key lessons are things that people already
pretty well understand, right? So one of the things is, you know, you want to write things
for reuse. And that means like writing things generically. There's lots of things about like
defining what should and should not be in interfaces. And this is the part that I think people don't take on board as well.
One thing in particular is that, you know,
they define what a basis of operations is.
A basis takes its name as analogy to like basis vectors in an N space, right?
So you have N basis vectors that are orthonormal,
and then that defines an N space.
Similarly, you can define n operations on your type.
And as long as those n operations on the type are defined,
you can do anything that that type is capable of just with some combination of those.
And as long as you can efficiently get to any behavior you want to using those types,
and that's the right, or sorry, those operations, that's the right set of operations.
And you don't want any more operations than that because that increases
test burden surface area it creates confusion all kinds of stuff like that so you want it to be
small but not too small you want to be efficient and then as long as that exists you can do
anything else and the reason you don't want to add anything else is because if you write free functions instead of writing a new
member, then when some other type, you've got your type T, some other type U, you write it in the
future, and it has very similar semantics in some aspect of what this type T did. Then all of a
sudden that free function you wrote, you can just use it and it works, right? This is the same idea
behind the algorithms library by one of the same two people, right?
Alex Stepanov,
Paul McJones being the other one.
The idea there was like,
we're going to write all these algorithms and not like hang an algorithm off of all these different data structures like vector and map and so on.
And I think that's the right way to do things.
And in fact,
I really think after going,
after having gone through the process of adding a new container-like thing
to the standard library, which is flat map,
I realized that I don't ever want to do that again.
I don't want anyone else to have to do that again either
because I think the right thing for something like flat map –
well, let me back up.
So what I'm talking about in particular is flat map,
because it's just cloning most of the interface of map it has things
like insert it has in place it has the square bracket operator it has try in place it has blah
blah has all these different things right and if you boil it down it's just try in place like
literally you can write try in place and all the others like in their in their description they say like we're going to do try and place and if that doesn't work then we're
going to create a new object and then we're going to try and place that's what square bracket is
defined as like roughly right um and so on and so forth like all the other kind of inserts are just
some permutation of try and place so that begs the question if we have map, flat map, multi-map, flat multi-map,
I guess the own order ones don't quite work the same.
But if we have that for the tree-like containers,
even if you have a flattened tree in the case of flat map,
why don't we have just like a free function that does insert,
that does in terms of try and place?
And then if you want to make your own map-like type,
you only have to define like, you know, 10, 12 functions,
something like that, instead of like literally,
I think for std vector, which is much smaller,
I think there was 64 members.
Yeah, and most of them are some form of in place, push back, or yeah.
Yeah, exactly, yeah. So if you had in place and in place push back or yeah yeah exactly yeah so if you had in place and in place back
um you know that that's all you really need right you can even have a branch inside of in place that
tells that it's at the back and it does the right thing right so you know that's that's that's a
generalization that that costs you some efficiency so maybe you don't want that but but you could get
there too so the long and short of it is i think people should be
writing more um containers because like let's say you've got vector and static vector and dynamic
or not dynamic vector what am i trying to say um small vector right that's what i'm trying to say
so small vectors along with a small buffer optimization then then it goes to the heap
if it can't if it can't do stuff there you really want to be able to write all those
really conveniently right um because there's no reason why you shouldn't have a vector-like interface for any of these things.
But people don't have a convenient way of doing that.
They have to repeat those 64 different ways of doing stuff.
So I think it's a big, fat bummer.
And David Stone, actually, he's another committee member.
He has a project that he's been working on for a little while to try to make the abstractions for all of the –
we have sort of these categories of containers in the standard.
So the vector-like ones are sequence containers,
and the node-based containers are – what do we call those?
We call them associative containers. So those are what we call the associated containers so those are
things like map and set and so forth so he's tried to do exactly what i just talked about right like
figuring out what that small basis is and let's make free functions for everything else
and he says he's still not happy with it he's been he's been working on it for a while but
i think that kind of thing really if people did more of that, then we would be better off. So the classic example to me is, and this is a real question I had at work.
Like someone said, well, I got this string view and it's got like find last not of or something.
So one of these algorithms that hangs off of strings and string views.
And he said, but I've got a span sometimes.
Sometimes I've got a string view.
Like, how do I do this?
And I said, well, you have to construct a string view from the span in order to get that algorithm.
It's dumb, but that's what you have to do.
And that's such an unsatisfying answer.
Like, why isn't that an algorithm, right?
And why don't we have just a set
of string algorithms that does string stuff, right?
I think that could work
really nicely.
Yeah.
It's,
I think once you learn more about
generic programming,
you start to become aware of the cost of adding a new type
and of added complexity in the interface of a type.
And it's like any time I either work around the committee
that somebody shows me their proposal for some new class does some great thing.
And it's got like a lot of knobs and bells and whistles.
My like first gut reaction is always like, all right, let's like take all those knobs and bells and whistles and like take them out.
And like, let's just get down to like, what are the core basis operations of this thing?
And it's because anytime that we add additional complexity
that we don't need,
one, it's typically a mistake that we can't come back and undo later.
But we end up in this world where we have things like string that have dozens of different
operations on it. And when we wanted to make another string-like thing, string view, we had
no choice but to make string view have all those same operations as well. And I think that that's
a much worse world than the world that we could have lived
in where we could have, we could have had some string algorithms and maybe we could
have introduced some sort of concept for string types.
And we could have had, um, some like string view would have looked a lot more like span.
It would have been a very simple thing.
And it would have been possible to have like a string, a string like concept where you
could just have your own string thing just satisfy that concept.
In the same vein as that, you know, when we added – I know a lot of people are happy that we're finally getting unstud string in the last couple of standards we've gotten, like contain, start with, and ends with.
And I complained so loudly in LEWG that we should not be adding these.
Like these are algorithms that we should
have with those names that work with strings and they said but they don't work for char star i'm
so let's make an overload that works with char star this is this is not hard to do we can add
that right and i was like even if we even if we start a new um section of the library like a sub
name space or or some kind of naming convention we have all the string algorithms over here in
their own little spot that beats having like to add this to string
and then string view
and then whatever else comes along later.
Because, you know, sometimes people are going to want
to have their own string-like thing.
And it doesn't have to be necessarily interoperable
with string or string view.
And they just can't make it work with generic code
without repeating all this API. And I think that's a huge problem. We want people to write quick and dirty code
that's reusable by everybody as much as they can, right? Because the testing burden for writing
complicated things is so high that we just don't do it, right? And so you have this untested stuff,
or you have stuff that just doesn't work in a generic context, because either I was going to
have to write these extra interfaces and test them, but since I don't want
to do that, I just don't write them or I don't test them. Neither one of those is a very good
answer. This is why this Boost library has steel interfaces, and hopefully we're going to
standardize this, but I have a class in there or a template in there that will let you write
iterators much more simply than repeating all thei of an iterator because what i found
was uh i was working on this other library that needed iterators all over the place for views and
ranges of things and every time i wrote an iterator i made like a subtle mistake and i started
realizing i was i was doing it a lot and so i was like why i should have glue for this this should
be easy and so i think we should try to if we're going to define interfaces that everyone needs to use, then we should define either really good glue that helps
them generate that code, or we should define them in such a minimal way that they don't need to
generate that code. Because all of these bugs that we're introducing, you know, there's something
like, I think that the industry standard when I learned this back in school was something like,
for every 100 lines of code, you've got a
bug and that's considered to be
a good defect rate. I'm talking about
the first draft.
The first time you write some code, people have done
some testing and stuff. They check it in
and then from that stage, we're not even
talking about just I banged out some
bullshit. This is actually
I've done my due diligence
and I've still got basically
a bug every 100 lines.
So if you can reduce the number of lines people write,
you reduce the defect rate.
It's sort of an inherent thing
to writing code, it seems. It doesn't seem to depend
on the language or anything.
But right now we have a lot
of things, particularly in the standard,
that don't lend themselves
to reuse that way.
I mean, I know very, very few people have ever written an iterator like and and you know whenever whenever
i have had to write an iterator i typically only write the operations that i am going that i know
i will need to use in my code yep and it's simply because like, if I need to show the code to somebody else,
I want it to be as like short as possible.
Yeah.
And the funny thing is like,
that will not fly with the ranges.
Right.
Because the ranges are actually like concepts.
Yeah, I know.
It's a real problem for me.
Yeah.
Well, you know, in a similar vein, you know, there's one of the things that we spend a lot of time talking about when we're designing new library facilities is I think the questions of like default constructability and the conversions that a type has comes up a ton
and like default constructability whether or not your thing can be default constructed
is usually like this huge question for your type because if it can't be default constructed then
there's a lot of context especially in generic code where your thing isn't going to be able to
be used but if it does you know if you are going to make a default constructed,
does your thing have some sort of null state or empty state?
And if so, what does that do to the invariance
of the rest of your thing?
And likewise for conversions, this question of when does your thing convert
and are those conversions implicit or explicit is a huge question in the design of almost any type.
Especially when there's, I think on the committee, we tend to like anything that has potential for performance loss to be explicit.
Yeah. Yeah. So I remember saying to a bunch of people at a committee meeting,
we're just hanging out after, you know, sessions.
And I said, I think I literally said implicit conversions are evil because
like so many people write so many of them and they cause all kinds of
headaches.
And then Bjarne who happened to be, said, no, they're not evil.
You just need to make sure that an implicit conversion converts between something that you're converting from and something you're converting to, where the to and from types are essentially the same thing.
And then it's natural and normal and everybody can reason about it.
So like converting between a float and a double should be implicit for that reason, for instance, right? It's questionable, and I think other languages have made a different decision.
I think I like the decision more that an integral value and a floating point value
maybe should not be interconvertible, right?
But that's a default we have from C.
And I think the question of whether something is default constructible,
and by the way, this is another one of the first six pages of EOP,
is the notion of regularity, right?
Like you have all these operations that are like,
if you're like an int, you're regular,
and that allows you to reason about your code.
And in particular, to do local reasoning about your code,
because you don't have to worry about things like the semantics of the code,
plus where do all these guys live in memory?
This one over here, that one over there.
Well, she lives over here and he lives over there.
I don't know if the alias to the same thing.
Like local reasoning is enabled by
saying well i can see the values and i see how they're used and the semantics of the the
operations that i'm doing is all i have to care about i have to care about lifetime and other
things like this um so the reason that default constructability is in there even though it's
not actually required for any of the algorithms in the STL like everything everything else in in regular is actually required to to operate with everything
in the STL and so you can see why that's a useful definition for someone who's going to write
something like the STL so someone asked Alex Stepanov one time like why is that in there it's
not it's not required unlike everything else he He said, well, it sure is convenient.
And to me, that's enough because, you know, part of that first six pages, he says, like, you know, you need to not just write, like, a basis of operations that, like, could work sometime.
And the example he gives is, like, what if you have a mathy kind of type, right?
So it does arithmetic operations.
Well, you could provide, like, minus but not plus, like binary minus but not binary plus.
And you could say, well, you just negate it.
Yeah, it's in there, right?
So, yeah, okay, you could do that, but it's incredibly inconvenient.
It's a type that you want to use for math, so you should be able to do that.
And I think default constructability goes under the same rubric, like is it convenient?
And if not, then why not?
So I think there are some types that really you cannot default construct because it doesn't make sense, right?
So something like a lock, I know there are patterns that people come up with where like
they want a default constructed lock. But I think really the 99.9% cases, the reason I'm constructing
a lock is so that in its lifetime, it holds the lock and that's what it's for and it shouldn't
do anything else. So I think that that should be not default constructable.
But I think most things we should definitely have regularity as part of them.
And in particular, since that statement from Stepanoff, we now have move semantics in the language.
Because that was an old interview, I think.
But now the argument to me is both convenience, the Stepanoff answer, but my new answer is, can you move this thing?
If you can't move it, then yeah, let's talk about it, whether it's default construct. But if you
can move it, I don't want to hear this, it changes the invariance because the invariance are already
that way. Like you have a move from state that you have to reason about. We don't have,
unfortunately, a destroying move operation in C++ where when you move something, it's gone. I don't
have to reason about it anymore. I think that's a better semantic, but we don't have that. The fact that I've got this
thing around and I have to have that in a set of things that I'm reasoning about when I look at the
value because it was moved from, that means that I have to be able to reason about that before
it's got a value as well. So I don't think there's anything wrong or messy about that.
I don't think it weakens invariance in the way that people claim that it does. I just don't
think it's a big deal. Yeah, I tend to agree.
Yeah. And I've had the same argument with a lot of people, a lot of very smart people. And in
some case, I'm the only one in the discussion that thinks this. And so I know it's not a popular opinion amongst especially a lot of
the sort of thought leaders in the community, but I really think it's the right answer.
Thanks for listening. We hope you enjoyed and have a great day.