AI Code Assistants and the Future of Software Development

AI code asssistant make coding faster and hence cheaper. We can either destroy software development jobs or increase the range of areas where software development is a cost-effective investment.

By Ryan McGreal. 1608 words. Approximately a 5 to 10 minute read.
Posted November 23, 2024 in Blog.

Contents

1Genuinely Useful
1.1 Autocomplete for boilerplate code:
1.2 Looking up obscure technical matters:
1.3 Modifying and refactoring existing code:
1.4 Writing Documentation:
2Strengths and Limitations
3What’s Next

I am a software developer and have been using GitHub Copilot since March. Here are some thoughts on what having an AI code assistant means for me, what it can and can’t do, and what it might mean for software development more broadly.

1 Genuinely Useful

First: I have found Copilot to be genuinely useful for me. My coding productivity, by which I mean how much code I can produce in a given time spent coding, has roughly tripled.

For the most part, I use Copilot in four distinct ways, three of them specifically code-related and the fourth code-adjacent:

  1. Autocomplete for boilerplate code
  2. Looking up obscure technical matters
  3. Modifying and refactoring existing code
  4. Writing documentation

I’ll consider each use case in turn.

1.1 Autocomplete for boilerplate code:

A lot of code is not fancy or innovative or even particularly complicated. In fact, clarity and simplicity are underrated virtues. Overly clever code can be hard to understand and troubleshoot when you inevitably have to look at it again later, and comments can only do so much.

When you’re writing workaday code, clarity and consistency and thoroughness are key. Naming conventions for methods and variables should be clear and predictable, and the code itself should be explicit and orthogonal. Each code block should do one clear thing, and errors or exceptions should be handled explicitly.

It’s tedious and time-consuming to write and when you’re in a time crunch (ie. always), you may be tempted to cut corners.

Copilot makes writing this kind of code a breeze. As long as you set up clear, predictable patterns when you start writing it, Copilot sails through adding methods and faithfully replicates those patterns so the code remains consistent and understandable.

1.2 Looking up obscure technical matters:

Modern software is extremely complex, with lots of systems stacked one on top of another, each layer hiding most of its complexity from the layer above it. To build applications effectively, a developer needs at least a working knowledge of several layers in the stack to run each piece of your code where it makes the most sense.

This is where one of my favourite eponymous aphorisms comes in: Joel Spolsky’s Law of Leaky Abstraction, which states: All non-trivial abstractions, to some degree, are leaky..

Which is to say, you can hide most of the complexity most of the time, but sooner or later you will encounter an issue where you need to get into the details to solve a particular use case.

Modern software has too many layers and too many implementation details to keep it all in mind all the time.

In the old days, developers would go to Stack Overflow, a question-and-answer website where developers post tricky or obscure problems and other developers show off their expertise by sharing solutions, and the community moderates the answers to bring the best on to the top.

You had to hope that someone had the same problem as you and that someone else knew the solution and was willing to share it.

Now, Copilot is extremely good at knowing the answers to these kinds of obscure technical questions. It has read every manual, every API document, every white paper, every monograph - and, yes, every question and answer on Stack Overflow.

I can direct Copilot Chat to look at the code I’m trying to write and describe what I’m trying to do. It will explain the solution and even write the revised code based on what I’ve been working on.

Instead of trolling through several Stack Overflow pages looking for a pattern similar enough to mine to be applicable, I get a custom-designed answer for my specific challenge - and I don’t even need to leave my code editor and switch to a browser.

1.3 Modifying and refactoring existing code:

In the same way that Copilot operates inside my code editor and has direct access to my code, it is also helpful for modifying and refactoring existing code.

Let’s say I have a form to add a record to a database and need to add a new field to the form. I need to modify the method that writes the form to add the field, and then I need to modify the method that receives the submitted form data, validates it and inserts it into the database.

Once I start writing the code to add the new field, Copilot anticipates what else I need to do and proactively writes the other pieces of new code to complete the change. If it needs a bit of guidance, I can always add a code comment on what I’m planning to do next and it will take the cue and offer a code completion.

Likewise with refactoring, or rewriting code to be better organized and structured without changing its functionality. Copilot has a large context window, which is the amount of information it can use to help answer your question, so it can read your code right in your code editor and propose improvements that are specifically tailored to your use case.

If you know which particular design pattern you want to implement, you can prompt Copilot with the pattern name - e.g. a Bridge pattern to separate an interface control from its implementation - and it will generate the code to do that.

1.4 Writing Documentation:

I was a fairly obsessive documenter before Copilot, but documenting what an application or API does takes time - especially if you want to be thorough. Now I write all my documentation as Markdown text in my code editor, and Copilot is there in the editor autocompleting my documents.

The generated text is not exactly enthralling, but it doesn’t need to be - indeed, the writing style should not be a distraction from its contents. And because Copilot has your code in its context, it’s quite good at autocompleting documentation which already understands the code it’s trying to document.

My documentation is better, it’s ready sooner, and I spend a lot less time on it.

2 Strengths and Limitations

To the extent that I know what I’m trying to code, Copilot makes me faster and more productive. It speeds up the code I already know how to write by writing it for me. It speeds up the code I’m not sure how to write by pointing me to the implementation details I need to solve trickier technical problems.

And it incentivizes me not to skip the boring busywork - the necessary but tedious code scaffolding, the dreaded documentation - that tends to produce technical debt if you yield to the temptation to postpone (ie. ignore) it.

However, writing code is only part of the job of a software developer. Before writing code, you need to be really clear on what you want your code to do. Depending on your organization, that might mean talking with team members who engage with your clients, or it might mean engaging with the clients yourself.

In many cases, your clients don’t quite know what they want either, or they think they know what they want and they ask you for specific implementation details instead of explaining what they’re trying to accomplish. So you often have to invest time and attention in a relatively unstructured series of discussions in which you ask open-ended questions and drill into the why and even the why behind the why.

Those discussions can feel time-consuming and even frustrating, but in my experience, it’s worth the investment to get to a deeper understanding of the real problem you’re trying to solve. That, in turn, can prevent a lot of wasted effort writing code that is superficially on-topic but doesn’t solve the real problem.

People who blithely claim that software developers are obsolete because AI can write code may not be reckoning with just how essential it is to understand both how to write code and also how to understand what the code needs to do.

In addition, while Copilot is freakishly good at knowing what code I’m writing and finishing it for me, it still occasionally gets it wrong. It's still essential to review any code that Copilot writes, even if it looks exactly how I was planning to write it, to make sure it has not introduced any subtle errors.

It's always a temptation, however, for a busy software developer to glance at generated code and decide it's good enough. In that way, the risk tradeoff of an AI code assistant is that you reduce the incidence of one type of technical debt but increase the risk of another type.

3 What’s Next

We are in the midst of an extraordinary AI hype cycle. Every company is trying to stick AI into its operations, products or customer engagement practices (or all three), and I think it’s fair to say the results are mixed.

I don’t mean to suggest that AI is all hype or that it has no real value. I’ve been using AI in my job for almost nine months now, and it has already become an indispensable productivity tool. But we can reasonably expect a boom/mania/bust cycle that leaves a few winners standing amidst a lot of failed efforts, stranded investments, and unmet expectations.

My hope is that, when the dust settles, we end up with some kind of synthesis in which the cost per unit of software development is going down but - and this is where my eternal optimism comes in - the number of use cases in which software becomes cost-effective to produce is growing in proportion.

Worst-case, we collectively cede control of the digital environment to robots working for billionaires. Best case, we are collectively able to displace more tedious, boring, error-prone and soul-crushing busywork with more humane and engaging activities that produce real value.