As developers, we are always searching for ways to make our code more concise, structured and understandable. Therefore, short code is preferred over longer code. This post explains why generally we find shorter code better and what some exceptions are.
The Good
Shorter code has many advantages.
It is generally faster to read. The total time needed to understand a section of code is greatly influenced by how many characters and statements there are. If it is possible to read through the code fast, one can start thinking about the code earlier.
A bugfix or feature addition to short existing code is often smaller. That is because fewer lines of code need to be changed. Smaller changes have the benefit of being easy to review and are faster to implement. In this way shorter code increases the maintainability of the code and might help with keeping the backlog of bugs manageable.
Short code is more elegant. As developers, we pride ourselves with the ability to craft elegant code. Expressive, concise, readable or efficient. These are adjectives we typically associate with elegant code. Personal pride might be a somewhat bad reason to do anything, but creating something to be proud of is important for personal motivation and “bonding” with the project.
Exceptions
There are some exceptions where shorter code is worse code. The following sections will give some examples to give an impression about the problems that can arise from short code.
Application of Multiple Functions
A very typical case of shorter code being worse is the application of multiple functions in a row to a container. Since functional code is becoming more and more popular, constructs like this become more common:
def get_birthday_by_uid(uid: int) -> time.struct_time:
return next(map(get_birthday, filter(lambda u: u.id == uid, users)))
The classic alternative is this:
def get_birthday_by_uid(uid: int) -> time.struct_time:
for user in users:
if user.id == uid:
return get_birthday(user)
The classical alternative has some major advantages:
- Each individual line is shorter, making the whole block easier to read.
- The individual steps are separated to a single line. This makes it easier to debug as breakpoints are usually set on a per-line basis. This also makes the code easier to read.
- The return statement is clear and not hidden inside some [0] at the end of the line.
- Programmers that don’t code in Python a lot, might not know what
next
,map
orfilter
do. But they know whatfor
andif
do.
sed
sed
is a small Unix utility that does what it is called: stream editing. It is very handy for on-the-fly editing of text streams. However, it is also typically the least maintainable part of any bash script.
Here is the “Hello World” example from the manual: sed '/^foo/d ; s/hello/world/' input.txt > output.txt
.
sed typically does a whole lot, with very short scripts. In the hello world example it searches for lines starting with foo, deleting these lines and replacing all “hello”s with “world”s. However, because nothing is written out explicitly (d for delete, s for search, what are the separators again?), one has to typically read the sed manual on encountering a sed script. Therefore, sed scripts are a great example of what happens when shortening the code at all costs.
Less Functions
Creating a new function adds more code. At the very least it will add a function signature and a return statement. A new function should also add one or more additional tests and a documentation block. The shorter version is collecting all the relevant code in a single function and making that function massive.
However, code with more functions is typically more readable, because it has more levels of abstraction and has more granular tests attached to it.
The rule that shorter code is better, should only be applied to functions in isolation. Each function should be as short and clear as possible and only deal with one task.
Shortening Symbols
Symbols (function names, variable names, …) should only be shortened if it is a generally accepted shorthand. Good examples are i for index, func for function, n for number or project-wide shorthands like I[Class] for Interface[Class].
When reading code, it is really helpful if it reads as English. There is some cognitive load to permanently expanding shortened names (i.e. cnt, idx, re, m for match, …).
Conclusion
There are good reasons, why keeping code short is mostly a good idea. But keeping a sense of proportion is also important. Generally it makes sense to check in the code that can be reasonably expected to be the fastest one to read. If the short code adds an additional layer of complexity, it might be a good idea to choose a longer variant. And if short code just reduces visual clutter and otherwise looks very elegant, it is a good thing.