I'd never used GPT... until today!
When all the hype about AI in programming started with GitHub Copilot I was not using VSCode plus the company I work for told us not to use it with any code from our clients. When ChatGPT came, a similar message also was sent to everybody. Put that together with my own recent career choice - to dedicate my time exclusively to code-related activities - and what happened is that I didn't care too much about all the hype until now.
Well, I've been reading, understanding, and discussing AI and how it relates to coding. I just haven't tried anything AI-related to help with my coding. And somehow I think that was a good decision. I didn't want a shortcut to get things done, I need mileage, I need to get my hands dirty with all sorts of programming problems, no matter how trivial. Apart from being fun, it's also the only way to re-learn some things that I ended up forgetting after a while (because, yeah, I forget very easily all the things - I might write about this in the future).
I was just peacefully coding.
But reading about something is not the same as using and applying it to a mundane activity. And that's what happened today. I was coding a very simple algorithm that a dear friend of mine was talking about with me. He said he was asked to code it in an interview and I decided to implement it in Golang as a challenge. I wouldn't look anywhere, I wouldn't try to find a solution or a hint of the solution online. The only thing I allowed myself to do was to search syntax-related things, because, as I stated above, I easily forget some things.
And during that activity, I ended up needing to implement a stack. I had some sort of a stack already but badly implemented in a string that I was manipulating throughout the code. So I did my own implementation of the stack, which took me around 15 minutes. Here is the first version I came up with:
// package and imports suppressed
type unicodeSlice []int32
type Stack struct {
unicodeSlice
}
func (s *Stack) Push(v int32) {
s.unicodeSlice = append(s.unicodeSlice, v)
}
func (s *Stack) Pop() {
lastElementPosition := len(s.unicodeSlice) - 1
if lastElementPosition >= 0 {
s.unicodeSlice = s.unicodeSlice[:lastElementPosition]
}
}
func (s *Stack) PopIfMatches(v int32) error {
lastElementPosition := len(s.unicodeSlice) - 1
if lastElementPosition >= 0 && s.unicodeSlice[lastElementPosition] == v {
s.Pop()
return nil
}
return fmt.Errorf("value to pop (%d) does not match provided value (%d)", s.unicodeSlice[lastElementPosition], v)
}
My idea was to have a regular stack, hence both Push() and Pop(), and an additional PopIfMatches() which was what I needed: a way to only pop the stack if the top value of the stack was a determined value that I could pass. If not, I needed an error, and that's what I decided to return.
Hunn, maybe I could see what AI is all about.
Right away, after getting the implementation working, I started to review it, as I always do. Then it came to me: well, do I need to do that? Let's see what GPT can do! A stack is a very common implementation, but I wanted to see what GPT would do with my "PopIfMatches" requirement.
I typed this: "Can you make a stack in Go with a special method that pop (sic) only if the value corresponds to a passed value?" and got exactly this:
// package and imports suppressed
type Stack struct {
items []int
}
func (s *Stack) Push(i int) {
s.items = append(s.items, i)
}
func (s *Stack) PopIf(v int) (int, bool) {
if len(s.items) == 0 {
return 0, false
}
lastIndex := len(s.items) - 1
lastItem := s.items[lastIndex]
if lastItem == v {
s.items = s.items[:lastIndex]
return lastItem, true
}
return 0, false
}
Right off the bat, I noticed:
-
PopIf
was easier to read than my code, with an early return for an empty stack. -
PopIf
returns a bool instead of an error to indicate the success or failure of the code. -
PopIf
also returns the removed value (or 0, which is the zero value for int in Go).
But then I also noticed a few mistakes I made (which, granted, I would probably fix them on my review, but anyway...):
- Returning a
bool
instead of an error made way more sense. I just needed to indicate the success or failure of the operation. The meaning of it is something that the caller could take care of anyway.- That also helps with making the implementation cleaner because I didn't need to import anything like I was doing with
fmt
.
- That also helps with making the implementation cleaner because I didn't need to import anything like I was doing with
- There was no need for me to have my own
unicodeSlice
type. I could make it a slice of the type I needed.
Not huge things, probably things I'd refactor right away or someone would get in a code review (in a real-world scenario), but still, things that are important. It took me less than 1 minute to formulate the prompt and get the implementation from the AI. Then a few more minutes to review the generated code and adapt it to my use.
Time is money. And money is what matters... for capitalism, at least
The time it took me to get the AI code and review it was still less than the 15 minutes that it took me to make the initial implementation from scratch, which would still require a quick review. Realistically, I would reward myself with a coffee or a quick walk around the house before getting into the review, so let's put that the final acceptable implementation, without the AI, would take around 40 minutes.
So it's around 10 minutes for the AI guided by the human against 40 minutes for the human aided by search engines. That's what capitalism is going to take into consideration! And I will go as far as saying that maybe that's already part of the reason we're seeing so many layoffs around the world.
Who am I? Or who will I become?
Is AI Code Reviewer a profession of the future? What about designing a whole application? Will there be something like AI Architect Reviewer? Is my next programming language the natural language?
So many questions, so many problems, and so little... time! Damn it! Who am I?
Top comments (4)
"That's what capitalism is going to take into consideration!" does it mean it is the right path?
You could say that it is the path the industry will take, no matter what.
And it is not something new. When in many big (huge) enterprises they tell you: "the most important thing is to have our client satisfied, no matter what the cost is" we usually end up with dirty code that in time becomes impossible to work with.
I have the feeling that we are forgetting what WE believe that matters and we do so little to be taken into account when the decisions are taken by managers and directors.
No. Not in my opinion, at least.
I think we're not forgetting. I, personally, am making sure others don't forget.
The text is about me wondering about the future. A superficial a analysis by "managers and directors" (although I'd put this differently) might take us to this future where I'd be a AI Code Reviewer.
That's not what I want, that I'm sure. But there's so little I can control. That's why I wonder...
I am not an expert but have been coding for more than 7 years now and when I first looked at your code I thought "why isn't he using the ok idiom ?" (aka "Returning a bool instead of an error made way more sense")
Is AI mandatory to tell us what we could do better? Or is our lack of expertise and experience that is making us glorify AI?
IMHO, programming is so much more than being the code reviewer of some AI produced code.
I thought about that too. I think I was copy&pasting code from the caller to my new file and didn't do a good job of reviewing. But as I said that's probably something I'd get in my review (or at least that's what I want to believe in), which I didn't do so I could compare with what the AI would do.
Nope. Not at all!
I think so, yeah. But also the fact that non-experts will be able to do things that you'd need an expert to before. Probably not good code, though.
100% agree.