What makes code hard or easy to read?
Let’s look at some practices that might lead to poor readability, and then we’ll look at how to get the readability as good as possible.
Why is reading code hard?
Reading code is much harder than writing code for at least three reasons:
- When writing code, you have to keep in mind the variables, algorithms, data, and structure of the feature you’re writing only. When reading code, you must keep in mind all the information about wider functionality and potential functionalities that you’ve guessed from your reading of the code so far.
- Thinking is easier than understanding someone else’s thinking – vastly easier.
- It’s not your code – your baby, so it’s probably not as good as something you could write, or at least that’s the thinking of many programmers. That’s the emotional aspect. Alternatively, you might be thinking that the code is written by someone more intelligent and experienced, so you’ll not be able to understand it.
To understand someone else’s code, you need a working model of the code in your mind, as well as the aims of the project [GameDev_Dieterich].
Don’t be afraid to read other people’s code and get an understanding of it. You may well make good use of it and not have to re-write the code.
This reminds me of the time I had to read and use code from colleagues in Czechia.
In addition to trying to understand the C code (when I would normally code in C#, R, or MATLAB) and learn some more physics, some of the variables were in Czech, which I don’t speak. So, I had to learn some Czech too. Fortunately, I enjoy learning languages and already know plenty about physics. Eventually, I understood the code and we worked together well, including visits to each other’s countries, UK and Czechia. We got some great products made.
Of course, if you can communicate with the original coder, you can ask them questions about it. Be polite – it’s their baby, which they might have taken a lot of time and energy to create.
Dos and don’ts of readable code – how to make readable code
Looking at the opinions of coders, the following are factors that make code difficult or a joy to read.
Do not do these things
- Inconsistencies, such as multiple different tab/indentation styles in one file or group of files or checking for a null and later checking for a non-null pointer, can confuse the reader who is trying to understand the code and ensure it’s working properly. Keep naming conventions consistent too.
- Use variable and function names that aren’t descriptive of what they are for, such as using celebrity names or movie titles even if the script has nothing to do with films!
- Using very similar function names can make bugs extremely tough to track down, such as
functionl()
andfunctionL()
. Make it easy enough for future coders (including yourself) to differentiate functions.
- Using very similar function names can make bugs extremely tough to track down, such as
switch
statement excess: when editing someone else’s code, don’t simply add aswitch
statement if your case is covered because that could lead to fall-through cases being dispersed randomly amongst the standard cases and make it a headache to read and understand [O’Reilly_Algo_Flow, Quora_Chen, StackOverflow_switch].- Use too many nested statements/layers of
if
statements: If anif
statement starts in the middle of the screen, there is probably too much nesting.
Do these things
- Code should contain different functions and functions should be simple:
- Function names should reflect what they do, and functions should be very simple: one task for one function, not multiple tasks in one function. Having such simple functions makes them easy to understand.
- An alternative to overusing
if
statements is to useswitch
statements.switch
statements are usually much faster thanif/else
statements too, especially when the number of conditions is large [O’Reilly_Algo_Flow, Quora_Chen, StackOverflow_switch].
Some strategies to effectively use LLMs for code generation
Provide clear and specific prompts:
- Be precise: Clearly articulate the desired functionality or task.
- Give context: Provide relevant information about the project or code base.
- Specify language: Indicate the programming language you want the code in and its version, such as Python 3.10.
Iterate and refine:
- Evaluate output: Carefully review the generated code for correctness and readability.
- Provide feedback: If the code is incorrect or needs improvement, provide specific feedback to the LLM – for example, “This code works but please make it easier to read, especially in the
Xzy
function.” - Iterate: Continue refining the prompt and iterating until you get the desired outcome.
Leverage LLM capabilities:
- Code completion: Use LLMs to suggest code snippets or complete unfinished lines.
- Function generation: Ask LLMs to generate entire functions based on a given description.
- Code explanation: Have LLMs explain existing code to better understand its functionality.
Consider contextual information:
- Project structure: Provide information about the project’s structure, dependencies, and conventions.
- Code style: Specify preferred coding styles or guidelines.
- Best practices: Instruct the LLM to adhere to best practices and avoid common pitfalls.
Combine human expertise with LLM capabilities:
- Human oversight: Always have a human developer review and validate the generated code.
- Domain knowledge: Leverage human expertise to ensure the code aligns with specific domain requirements.
Here is an example prompt:
"Write a Python function to calculate the factorial of a given non-negative integer."
Here is the LLM response:
Python:
def factorial(n): if n == 0: return 1 else: return n * factorial(n - 1)
Use code with caution.
Note
While this code is correct, a human developer might suggest improvements, such as adding type hints or using a more efficient iterative approach for larger values of n.
Remember
LLMs are a valuable tool for code generation, but they should be used along with human expertise to ensure the highest quality and maintainability of the code. By following these guidelines and iteratively refining your prompts, you can effectively leverage LLMs to enhance your coding productivity.
Learning to read code does take practice, so keep practicing, and you’ll find it easier and more productive with time and work. Collaboration is one of the most powerful tools we have to make amazing things!
This section has been about bad and best practices when writing or generating code with LLMs: don’t use too many if
statements, don’t make the code overly complex or with no comments, and don’t just add things randomly; do go back and forth with the LLM, provide the desired language version and context, such as the project structure, evaluate the code yourself, write simple functions, use descriptive names, document the code nicely, follow coding standards and conventions, handle errors, and so on. We looked at some code that’s hard to understand and some that is easier to read and understand, and where to get the code from the Packt GitHub repo. The next section is on how to summarize code you don’t understand.