Hello, and welcome to C++ Weekly. I'm your host, Jason Turner. In this episode I want to
ask the question as to whether or not and when we think that AI might start replacing programmers.
[Music]
Now of course I want to remind you to check out all of the links in the video description
so that you can support this channel and become a member and subscribe because those
are important things for the livelihood of a YouTube channel. So you've probably heard of
this ChatGPT program which is part of OpenAI, and if you have not actually seen this before,
I'm going to run through a few examples to kind of illustrate why I've been thinking about this.
So you have this chat prompt here and you might type in something like this,
and I'm asking the chat bot to take the C++ 98 code and convert it to C++11 code.
Now it did skip a step here that you might have noticed, and it went to C++17 directly
even though I asked specifically for C++11, but I would say it did a pretty good job of
it. It determined that it can use a structured binding, it explains the things that we did here,
and it has given appropriate names to these two variables, and it looks pretty good.
It's using a ranged-base for loop, but we could further ask it to do work like
convert this last thing to use lib{fmt}, which you've seen on this channel before,
which is a really well-done tool; and as you can see it can do that with no problem at all; and as
far as I can tell this code looks all correct to me. Then you can further ask it to do things like
convert this last example to Python, and it does, but if you're familiar
with Python then you might know this is not the best way to do this. So I can ask it to
update the Python example to you string interpolation.
...and there we go, that's looking like a pretty good Python example. It does assume
that 'map' and 'dict' and things like that are strings and integers, but now we start
to wonder what happens if I say something like, "Convert this Python example back into C++98."
Well, that looks pretty good. It added in an end line, which you know that I don't like,
but it looks like it did a pretty good job on that as well, so it's clearly not just regurgitating
the first thing that I asked it for. That's pretty cool, but then we can do things like
say I want to create a templated C++ function to compare any two values.
Let's give it the correct wording here with a less than comparison.
Okay. That looks pretty good, and it even gave an example for how to use it,
although it doesn't know that you don't actually need to pass that template parameter, that
template type deduction would work out there, but I could do something like
ask it if it can use the 'auto' concept.
Yeah, no, it didn't actually gain anything there. It says that it uses the 'auto' keyword
but it doesn't. Let's try again. I want to limit the C++ code to only integral types.
There we go. So it used the terse syntax now. It's requiring them to be the same type, 'T',
but that looks pretty good. This is one of my more interesting experiments that I've done with this.
Now I've tried this before in a different line of questioning,
but I'm tired of people always passing 'T' as the template type,
so let's just see what happens if I ask for a more meaningful name.
No, it just lost the last change there. So, you know, are these going to replace
programmers? Maybe not yet, but it's still pretty good. Let's see if we can say...
I want it to add some catch2 test for me... there we go, REQUIRE_FALSE. Yep. That seems... to that
seems to be pretty good. I wonder if I can ask it to make the previous version constexpr.
Okay, good. That's not bad at all right there.
Let's see if it knows how to use static_assert or not.
(And just for the record, I am intentionally not speeding any of these things up.) There we go. So
it added some static_assert compile time enabled test for our constexpr enabled less than function.
Pretty spectacular, huh? I mean, um, maybe not replacing programmers yet, but let's try another
line of questioning. I really think that it should be best practice to prefer .at() instead of the
bracket operator (the index operator) when you are using std::vector, for example, because then you
can accidentally iterate past the end of it. So let's go ahead and do something like this:
I'm going to ask it to make a Clang-tidy check for me
that prefers the .at() member function
over the index operator when it exists for the
type being operated on
and when the .at() member and index operator take the same type
and that type is integral. Now I've tried various versions of this already in the past,
and it does a surprisingly good job. It's going to take a minute. I haven't actually tested this
code to compile, and obviously I don't even know if this is going to give me the same
result because as a human I give it different wording each time I play it along these lines.
Again, I am making a point of not speeding any of this up, we might need to take this
example and put it in the other OpenAI playground, but let's see what we've got -
"prefer .at() over index operator," its Clang-tidy check. Let's see...
we're gonna have to scroll back on this. This assumes that I'm familiar with the
Clang-tidy framework, etc. Let's see - it has RegisterMatcher, it looks for
an index expression that has an argument that is an integer literal. That might be a little
bit step too far, I just want it to be an integer type, not an integer literal, but
then that builds us the expression; and we take that expression down here when we do the check,
and we see "prefer using .at() member over index operator," and it looks to see...
CreateReplacement, okay, so does the CreateReplacement... Well,
let's just go ahead and ask it to, well,
let's go ahead and see if it can properly add some unit tests for this Clang-tidy check.
So it's not, in this case, creating an explicit clang-tidy style check here,
but it did create, I think, a catch... that looks like catch to me perhaps - uh, no,
Gtest, that might, well, whatever. It created some unit test for us as well
that calls those functions directly. Well, that's pretty good, and just in case you wonder, like,
how limited this thing is... If I really wanted to I could do something like this:
That looks pretty good. It's iterating from 1 to 10 and printing out "Jason Waz Here" on
each loop iteration. Yeah, I would say that that is pretty much exactly what we asked it to do,
but I hate end line, and I'm just going to ask it nicely
(I've never phrased it quite like this before) and I'm gonna see what it does.
Much better, uh, although, again, now we're really pushing it past things that I've
asked it to do in experiments before recording this episode; but let's go ahead and do this.
Now at this point you start to wonder if there's actually
a human involved here. It does actually tell us that "it can be printed to the standard output
stream in a single step... simplifies code (and) makes it more efficient."
Okay, very good. It's "(an) older and less powerful programming language." Thanks.
I have no idea if this is going to be able to do this or not, but you know, this is one of these
annoying things when you're actually programming in Basic with line numbers, and you end up saying,
"Oh no. I created lines 21, 22 and 23 and I need to insert line 22 and a half."
Well, it was able to do that. It's pretty impressive really. Okay, so we have this
simple example in arguably C, not C++, that for 0 through 4 prints "Hello" and then prints "World."
So let's see, it prints "Hello," and then it prints "World," and then it subtracts one
from the counter if it's not zero yet; then it iterates up, so it starts at five and it
counts down. Now we're going to try this and we're going to see what the chat bot can do with this.
Yeah that looks pretty...
pretty accurate. You know I don't like end line, and it keeps using it even though I
tell it repeatedly to not use end line. So let's see what happens if I convert this into C.
That's better. That's right back to the 'puts' that I had earlier.
Let's see if we can take this entire example full circle.
That might be correct, I think that might be correct.
Of course it complains all along that Commodore 64 Basic is old.
Now of course we would want to know how to do this on a BBC Micro as well.
A state for the record that at this point,
very little of what I'm showing you was actively planned - this is...
just examples that I thought of on the fly. So we will give one further test,
and this is the one that first blew my mind when I was playing with this.
You can ask it to create programming exercises for you, besides being able to
modernize and de-modernize code and convert between different programming languages and
disassemble and create complex tests for us and add unit tests for our programs.
We could do something like this. Let's see, the exercise is "Write a Python function 'is_prime'."
Well, look. It even use typed Python. That's rather fancy,
and I didn't really like that one.
This definitely raises lots of questions of course about code ownership, copyright, um,
the meaning of creation and all kinds of stuff. I find this all very interesting and the results
that it's giving us are are fascinating indeed. So I hope that you liked this episode of C++ Weekly.
It was perhaps a bit slower than usual. So be sure to subscribe and catch you in the next episode.