Less code doesn’t always mean more readable code

Sumit Saha
5 min readMar 8, 2023

--

Here is an example of JavaScript code that demonstrates how writing less code doesn’t necessarily result in readable code:

const a = [1, 2, 3, 4, 5];
const b = [6, 7, 8, 9, 10];

const result = a.filter(x => x % 2 === 0).concat(b.filter(x => x % 2 !== 0)).map(x => x * 2);

console.log(result);

Output:

[4,8,14,18]

This code uses functional programming concepts to combine two arrays a and b, filter them based on whether the numbers are even or odd, and then double each number in the resulting array. The code accomplishes all of this in just one line.

However, while this code may be concise, it is not necessarily easy to read or understand. The use of several function calls chained together makes it harder to follow the flow of the code, especially for someone who is not familiar with functional programming concepts. In addition, the use of one-letter variable names (a, b, x) makes it harder to understand the purpose of each variable.

A more readable version of this code might look like this:

const firstArray = [1, 2, 3, 4, 5];
const secondArray = [6, 7, 8, 9, 10];

const evenNumbers = firstArray.filter(number => number % 2 === 0);
const oddNumbers = secondArray.filter(number => number % 2 !== 0);

const doubledNumbers = [...evenNumbers, ...oddNumbers].map(number => number * 2);

console.log(doubledNumbers);

Output:

[4,8,14,18]

This version of the code is longer, but it is easier to read and understand. Each step is broken down into separate variables with descriptive names, making it clearer what each part of the code is doing.

Example 2

Here’s a more complex example. Suppose you have a list of books in an array of object like below:

const books = [
{
"title": "The Hobbit",
"author": "J.R.R. Tolkien",
"year": 1937
},
{
"title": "Brave New World",
"author": "Aldous Huxley",
"year": 1932
},
{
"title": "1984",
"author": "George Orwell",
"year": 1949
},
{
"title": "Animal Farm",
"author": "George Orwell",
"year": 1945
},
{
"title": "The Catcher in the Rye",
"author": "J.D. Salinger",
"year": 1951
}
];
const recentBookTitles = books.filter(({ year }) => year >= new Date().getFullYear() - 10).map(({ title }) => title).sort();

This code uses destructuring, arrow functions, the filter method, the mapmethod, and the sort method to achieve its goal in a single line. However, it may be difficult for someone unfamiliar with these features to quickly understand what this code is doing.

On the other hand, we could write the same functionality in a more verbose, but potentially more readable way:

const recentBookTitles = books
.filter(book => book.year >= new Date().getFullYear() - 10)
.map(book => book.title)
.sort();

This code uses the same methods and concepts as the previous example, but spells out the property names and function parameters, making it easier for someone unfamiliar with these features to understand what is happening.

Example 3

Here’s a final example to conclude this guide:

const calculateScore = (scores) =>
scores.reduce((total, score) => total + score) / scores.length;

const hasPassed = (scores, passThreshold) =>
calculateScore(scores) >= passThreshold;

const displayResults = (studentName, scores, passThreshold) => {
const passStatus = hasPassed(scores, passThreshold) ? "PASS" : "FAIL";

console.log(`${studentName}: ${passStatus}`);
};

const students = [
{ name: "John", scores: [90, 80, 70] },
{ name: "Sarah", scores: [60, 70, 80] },
{ name: "Mike", scores: [50, 60, 70] },
];

const passThreshold = 60;

students.forEach((student) =>
displayResults(student.name, student.scores, passThreshold)
);

At first glance, this code may seem concise and easy to read. It calculates the average score of each student, checks if they passed based on a certain threshold, and displays the results.

However, upon closer inspection, the code can be difficult to follow. The use of arrow functions and ternary operators can make it difficult to determine what each function does and how they are connected. Additionally, the lack of comments and descriptive variable names can make it challenging to understand the purpose of each line of code.

In this case, writing more code by using more descriptive function names, comments, and breaking the code into smaller, more manageable functions can improve readability and understanding.

Here is an example of how the code could be refactored to be more readable:

function calculateAverageScore(scores) {
const sumOfScores = scores.reduce((total, score) => total + score, 0);
const averageScore = sumOfScores / scores.length;
return averageScore;
}

function didStudentPass(scores, passThreshold) {
const averageScore = calculateAverageScore(scores);
const hasPassed = averageScore >= passThreshold;
return hasPassed;
}

function displayStudentResults(studentName, scores, passThreshold) {
const hasPassed = didStudentPass(scores, passThreshold);
const passStatus = hasPassed ? "PASS" : "FAIL";

console.log(`${studentName}: ${passStatus}`);
}

const students = [
{ name: "John", scores: [90, 80, 70] },
{ name: "Sarah", scores: [60, 70, 80] },
{ name: "Mike", scores: [50, 60, 70] },
];

const passThreshold = 60;

students.forEach((student) =>
displayStudentResults(student.name, student.scores, passThreshold)
);

In this refactored code, the functions are more descriptive and have more meaningful names, making it easier to understand what they do. The calculateAverageScore function now has a clearer name, and its inner workings are broken down into multiple steps with meaningful variable names. Similarly, the didStudentPass function has a more descriptive name and returns a boolean value indicating if the student passed or not.

The displayStudentResults function now calls the didStudentPass function, making it more readable and easier to understand. Lastly, the variable name passStatus has been renamed to status to be more general, which could be useful in case the code needs to be extended later.

Overall, these small changes can significantly improve the readability and maintainability of the code.

Conclusion

In conclusion, code readability is an essential aspect of programming that affects the quality and maintainability of software projects. Readable code is easy to understand and modify, reducing the time and effort required for debugging and updating code. It also improves collaboration among team members, making it easier for others to understand the code and contribute to the project.

To improve code readability, developers should follow established coding conventions and best practices, such as using meaningful variable names, writing clear comments, and organizing code into logical structures. Additionally, tools such as code linters and style checkers can be used to enforce coding standards and identify potential readability issues.

Overall, prioritising code readability can lead to more efficient and effective programming, resulting in higher-quality software projects that are easier to maintain and evolve over time.

--

--

Sumit Saha

A Full Stack Web Application Developer from Bangladesh 🇧🇩 & a Programming Content Creator. Spend most of time coding outstanding projects or creating contents