Code Smell 219 - Looping from index 0
Counting from zero seems natural. Doesn't it?

TL;DR: Start counting from one instead of zero. Like humans do.
Problems
Bijection from real-world broken
Cognitive load
Overly implementation-oriented code
Solutions
- Favor high-level declarative languages
Context
Low-level languages force you to think at a machine level.
Hardware turning machines were designed to use binary gates and start indexing at 0.
A few programming languages use one-based indexing, where indexing starts from 1.
These languages are known for being higher level and more declarative:
Basic / Visual Basic
Pascal
Smalltalk
Fortran
Lua
MATLAB
R
Julia
Sample Code
Wrong
package main
import "fmt"
func main() {
numbers := []int{10, 20, 30, 40, 50}
for i := 0; i < len(numbers); i++ {
// Iteration goes from zero to len-1
fmt.Println(numbers[i])
}
}
Right
numbers = [10, 20, 30, 40, 50];
% Looping through the array using one-based indexing
% from 1 to length
for currentIndex = 1:length(numbers)
disp(numbers(currentIndex));
end
Detection
[X] Automatic
This is a language smell.
Exceptions
- Low-level optimized code
Tags
- Declarative Code
Conclusion
We need to think as humans when we code and not as machines.
Humans count from one.
Zero number was a brilliant discovery in math and science but it does not apply to everyday counting.
Relations
More Info
Disclaimer
Code Smells are my opinion.
Credits
Photo by Andy Kelly on Unsplash
Pay attention to zeros. If there is a zero, someone will divide by it.
Cem Kaner
This article is part of the CodeSmell Series.
My new book about clean code is available for pre-order.
You will find several recipes like this one with a higher level of detail
About the author
I’m a senior software engineer loving clean code, and declarative designs. S.O.L.I.D. and agile methodologies fan.
Comments
Join the discussionMy two cents: I get the point and it has some merit. However, I disagree with the idea of starting with 1, because in computer science indices of arrays, lists and so on usually describe an offset in memory. Index 0 means that there is no offset, so you're at the beginning of an array, you haven't moved the pointer to a different position inside the allocated memory. I know that this adds cognitive load, but adding an abstraction which shifts this logic only makes it more confusing than knowing and understanding that in programming you always start at 0.
Hi. this is true when you talk about pointers.
That's why I explicitly mention the rule does not apply to low-level optimized code.
Most software is unrelated to pointers but to human concepts. that's why you should prefer one-indexed languages. IMHO
Maxi Contieri Well, most programming languages use a representation for arrays and similar data structures with contiguous blocks of allocated memory. Should we abandon modern programming languages just because of this? I don't think so and I don't see the need. For matured developers, this should be a non-issue.
I am aware most programmers still work as if they were low level.
Should we keep doing it this way because of the status quo or we deserve something better?
This is an issue for any junior or senior developer since it brings lots of cognitive load. Imagine the available space on your brain to make amazing things when you discard this accidental complexity about talking to machines.
Again. this article is just my opinion
Maxi Contieri I'm not questioning your opinion, I already acknowledged that it has merit in my first comment.
What's your proposal, though? How should we proceed? Introduce massive breaking changes into all existing software? Use entirely new programming languages and rewrite everything?
I don't think that changing this is realistic or needed. Once you're used to it, the cognitive load gets less. At least that's the case for me, I cannot speak for every software developer.
I appreciate your blog post, because it does question things as they are being done and shines a light on the cognitive difficulties this produces (at least for some people, especially beginners).
We have too many accidental problems with languages and the way we use them.
We need to be smart and know the cost of mistaken implementation decision so we can make good ones as long as we can.
There's room for change if we ack this is a problem. Maybe we cannot change the way we address indices, but we can change many high level decisions
Maxi Contieri I agree that we should learn from past mistakes and improve language design. This is already on-going, maybe not for indices, but some languages, like C#, are evolving fast with user-friendliness in mind.
Code Smells
In this series, we will see several symptoms and situations that make us doubt the quality of our developments. We will present possible solutions. Most are just clues. They are no hard rules.






