Programming Beyond Cognitive Limitations with AI

Our natural processing power is limited, and leveraging AI for assistance can help us to use it more efficiently, especially when it comes to reading and understanding code.

Grokking new code requires cognitive load — and can sometimes trigger cognitive overload — which can slow our learning and onboarding to new codebases. We can use AI can help us to work around some of these natural limits: by comprehending and understanding code faster, we can learn more efficiently and dedicate our focus to higher-level coding tasks.

The Programmer’s Brain, written by Felienne Hermans in 2021, applies cognitive science concepts to programming to improve the way that programmers understand and think about code. The book provides concrete, actionable techniques aimed at helping programmers to work within cognitive limitations to be more efficient. Recent leaps in LLMs (GPT-4) made me think about how we might be able to work above our cognitive limitations by getting assistance from AI, and I think we’ve reached a point where this is possible in a meaningful way.

Let’s talk about how AI can augment our processing power by tying cognitive science concepts to specific programming tasks we can offload.

Cognitive load limits

One of my biggest learnings from The Programmer’s Brain was about our specific cognitive load limits:

  • Our short-term memory, which we might use to understand what value a function will return, can hold about two to six things in (for about 30 seconds)

  • Our working memory, which acts as a processor, might be used for mentally compiling and ‘executing’ a call stack and is only capable of processing two to six things at a time

That is… not a lot of things! We bump into these limits sooner when we’re working with the unfamiliar — information which isn’t stored in our long-term memory for easy access.

Working with the unfamiliar is pretty common for programmers: research indicates that almost 60% of programmers’ time is spent understanding rather than writing code (citing The Programmer’s Brain again here). If we can use AI to understand code faster, that AI has the ability to be transformational for our productivity — both at the individual and team levels.

Grokking Unfamiliar Code

In The Programmer’s Brain, Hermans states: “All unfamiliar code is confusing to a certain extent, but not all code is confusing in the same way.” As programmers encounter new code, we might find it confusing or hard-to-follow for a myriad of reasons. Lots of things can make code confusing, from poorly-named variables to confusing structure to well-written but complex code.

Hermans outlines three main sources of confusion and ties them to our cognitive processes:

  • Lack of knowledge means that you don’t have the knowledge you need (in terms of syntax, for example) to grok the code you see. This is associated with long-term memory because that’s where we store syntax that we use often.

  • Lack of information means that the info you need to understand code is not readily available but can be found elsewhere (for example, in another part of the codebase). This is associated with short-term memory because while you have the understanding, you don’t have all of the context needed to mentally validate code.

  • Lack of processing power occurs when you have the knowledge and information to mentally trace code, but you run out of room to hold intermediate steps and hit the point of cognitive overload. This is associated with working memory, which functions as our processor, forming new ideas and solutions.

In experimenting with GPT-4 (via ChatGPT), I’ve found that each of these sources of confusion can be addressed directly by using AI to augment our knowledge, information, and processing power, in turn.

Overcoming Lack of Knowledge

If we were to encounter the following APL code in the wild, we might not know how to evaluate it due to a lack of knowledge around APL and its operators and syntax:

2⊤D

APL is a programming language from the 1960s, so we’d be forgiven for not knowing that the ⊤ operator is an encode function, which converts numbers from one base to another — in this case from decimal to binary. Pre-AI, you might get this knowledge by Googling the operator, reading documentation on APL syntax, and eventually mentally evaluating the code.

AI speeds up this process dramatically. Asking ChatGPT (like I have below) gives us the knowledge that we need to evaluate the code quickly, without us having to hunt, gather, and synthesize information to build the basic understanding:

AI can generate a basic understanding of the code, and now the task for us to do is to verify it — which is generally much faster than synthesizing. We can copy code to run it ourselves, and because ChatGPT has defined what’s happening at each stage, we can mentally evaluate the code ourselves and Google anything we’d like to double-check.

So, AI can help us to understand code more efficiently by doing the work of gathering and synthesizing knowledge, allowing us to move from learning to application more quickly.


Overcoming Lack of information

To simulate how AI might help us to quickly glean information which lives in other parts of a codebase, let’s look at one of my Advent of Code solutions from a couple of years ago:

I wrote this code (😅) and I’m not sure what it’s actually meant to do. There are some hopefully-descriptive variable names, but it’s not clear from the function’s logic what the goal of the puzzle was. This is an example of a time where I have appropriate knowledge of Python to evaluate the code, but not enough information to do so. Pre-AI, I would get the information to understand code without context by searching the codebase for where key variables and functions in the code are defined or referenced.

Because Advent of Code data is in the training set for GPT-4, we can use AI to gather the information needed to quickly understand what this code is meant to do — simulating what we might do if our codebase was part of the training data for an AI. As it turns out, asking GPT-4 what this code does is a remarkably efficient way of gathering relevant information.

This is pretty amazing. ChatGPT gave me:

  • a high-level description of the puzzle the code is solving

  • a description of the puzzle inputs (instruction directives)

  • a summarized list of the lists I created to solve the puzzle, along with a description of each

  • a description of what my code is doing

From here, I can cross-reference anything I want to further verify, or pick up where I left off in this part of the ‘codebase’, while saving a bunch of time.

I mentioned earlier that AI has the potential to help both individual and teams to become more efficient. Imagining an AI trained on your codebase, and specifically focused on how we can improve reading, you could:

  • Automatically create and update documentation to summarize key parts of the codebase and onboard new team members

  • Create maps and architecture diagrams of how code from different parts of the codebase work together

  • Function as a chatbot to answer specific questions about code, like what it does, or what downstream impacts a change to one part of the codebase might have

Overcoming Lack of Processing Power

Our working memory (“processor”) is capable of processing two to six things at a time — an important limitation when we consider our ability to trace and evaluate code through a series of functions.

Evaluating the values (state) of each variable at each stage in execution of code can require significant cognitive load, sometimes veering into cognitive overload. When this happens, we’re encouraged to write things down to simplify the processing in our working memory — often, for example, as dependency graphs or state tables. In the longer-term, mental models (committed to long-term memory) can help us to more efficiently grok code.

The following Python code is meant as a simplified example of this — it takes eight steps (one of which is a while loop) and three variables to define a function which inputs a decimal and returns a binary number:

Keeping all of this state (especially with that while loop) in our brains while trying to understand and evaluate this code requires some serious cognitive load. Pre-AI, our option would be to add print statements or breakpoints to our code, or to go analog: write things down somewhere as we work through it.

Using AI, we can automate this process and get to understanding faster. In the example below, I’ve asked ChatGPT to annotate each line with the current value of each variable at each point:

This is helpful for quickly explaining the code, and understanding what one run of the loop looks like. But let’s say that we’re interested in the states of each of these variables during a following iteration of the while loop — in a pre-AI world, we’d probably be creating a state table or evaluating a version of the code offline to understand how data moves through it.

Now, we can just ask AI to do that for us:

Et voila! We don’t need to contend with cognitive overload to get to our end goal of understanding even the nitty-gritty of the code we work on.

Being able to quickly trace state through a codebase is an outstanding application of AI for developer productivity. Perhaps ironically, this is particularly applicable for machine learning — where both your data and your code are subject to frequent changes, and understanding the state of data for many data inputs at a specific point in the code base is a key component of debugging ML pipelines. I wish I had this five years ago, when I spent months doing exactly that.

Onward

I’m very bullish on the ability of AI to meaningfully improve developer efficiency by augmenting our own processing power. As a full-stack data scientist with over a decade of tech experience — and just about as many years hearing overhyped AI pitches — I’m an optimistic skeptic about most things, with a heavy skepticism for “AI” (scare quotes very intentional), but I think this is real. We know that AI isn’t perfect, so being able to validate its outputs is a necessary skill when using it to build understanding around code syntax and meaning. AI doesn’t have to be perfect to be meaningful.

We’ve reached a point where AI can meaningfully help us to work above our own cognitive abilities, and there’s going to be a meaningful shift in productivity for those who spend the the time to learn how to use it to help their own workflows. I’d encourage everyone to consider how AI can help them to be more efficient as they’re tackling their current tasks, and to consider what the implications of AI mean for what’s next. If you’re using AI in a unique way to improve your own efficiency, I’d love to hear about it.

Previous
Previous

A Framework for Making Decisions with Data

Next
Next

Delegation is a superpower