Why For Loops Bad

Table of Contents

Hello, and for today’s post, we are going to make my first post that actualy has content. I wasn’t sure what to write about, but I guess I wanted it to be somewhat short yet meaningful. Then I remembered something I heard from a while ago,

I just feel so productive using C. Just being able to use a for loop just feels so great!

Which is one of the stupider things I’ve heard in my life. Because C suxx and for loop: bad

(I guess the context for the quote is important. We had recently been programming in assembly. Writing in C is like eating dirt, but writing in assembly is like eating cyanide. )

So why is C bad? Well, for a lot of reasons, but today we are focusing on just one: the for loop.

Now you may be thinking: What’s wring with a for loop? I use it all the time.

Well, that’s because you’ve been brainwashed by Big For Loop™ into thinking that the for loop is acutally something good. It’s not.

Let’s look at a typical example of the for loop.

int sum = 0;
int n = 12;
for (int i = 1; i <= n; i++) {
    sum += i;
}

Here we are summing up the numbers from 1 to n, and I just set n to 12.

Lets look at another example

int array = {1, 2, 5, 8, 9, 0};
int sum = 0;
for (int i = 0; i < 6; i++) {
    sum += array[i];
}

Where we sum up the values in array.

Besides the fact that you can’t get the length of an array in C, these examples don’t look too bad. But they are.

1. Advantages of the for loop

What are the alternatives to the for loop? The most obvious choice is the while loop, which is very similar, in fact

for (A; B; C) {
  D
}

Is the exact same as

A
while (B) {
    D
    C
}

(Minus a bit of a technicality of the scoping rules, since the scope of a variable declared in A will be local to the loop)

The advantage gained here is honestly not much. You save two keystrokes typing for instead of while, and it’s easier to check if you accidently omitted C. But you could also get the same effect by just typing C before D in the while loop, and then it’s basicalyl the same.

2. The “other” for loop

Many languages have noticed how stupid this version of the for loop is, and ontly the really stupid languages keep this “C-style for loop”. This is because even though, A, B, C could all be anything, people only realy write one type of for loop.

for (int V = Init; V < End; V++) {
    D
}

where V is your choice of variable (usually i), Init your initial value End being your end value (though sometimes it is an expression).

And occasianlly they use <= instead of < to confuse you into making an off by one error. And maybe also switch ++ to -- or even rarely V += X for some X

The above pattern is so common, that if I saw someone being creative with A, B, C, that wasn’t the above, I would assume they wrote a bug.

An language with a more reasonable for is lua, which has a more reasonable syntax.

for A = Init, End do
  D
end

It’s basically the C for loop, but there is no redundancy, beceasue you anly change the parameters that you expect to change.

But even this is actually rarely used, because the most common used case is not actually dealing with integers, instead you are actually dealing with indeces in order to access array elements. But do I really need indeces most of the time? This leads us to…

3. The other other for loop

This for loop, also known as the for each loop, is probably the most common for loop you see. Here’s an example of the python version.

for element in my_array:
    do_stuff()

Lots of other languages have this or some variant of it. Even some older languages such as Java or C++ have introduced this as an alternative to the C style loop.

What are the benifits of using this, besides not having to type as much? The main benifit is that your the code is closer to your intent. When you think at a human level, you often say something like “call a function X with all the elements in the arary” or “select only the elements that are X in the array.” It is very unnatuaral to think about introducing an index, when most of the time it isn’t needed. Instead, we just talk about the elements, and talking about what we want to do to the element, or inspecting the element for some kind of property.

By taking the index out of the picture, we have a simpler transition from our mental model to code and vice versa. And we can potentially avoid a stupid mistake.

Compare the snippets above with a python version.

total = 0
n = 12;
for number in range(12):
    total += n
array = [1, 2, 5, 8, 9, 0]
total = 0;
for number in array:
    total += number

Notice that in C, summing up numbers can be seen as a specialized case of summing an array, as range can be viewed as creating creating an array. This is the opposite of C, where summing an array is seen as a specialized case of summing a range, where you add the array element corresponding with index intsead of the index itself.

And it should be like this, because accessing the array elements is the common case, while doing stuff with the indeces is rare.

But can we do better than this?

4. Getting rid of the element

array = [1, 2, 5, 8, 9, 0]
total = sum array

OMG it’s so easy. Well, you could have also done the same in python too. But Python is stupid, because it is mainstream and I hate all things that are main stream.

Sum in general can be with replaced with foldl, which more or less means loop over an array and end up with some kind of total.

array = [1, 2, 5, 8, 9, 0]
acculumulate currentTotal element = currentTotal + element
total = foldl accumulate 0 array

or more concisely

array = [1, 2, 5, 8, 9, 0]
total = foldl (+) 0 array

So this is nice because we can easily generalize it to other things, such as writing it for product.

array = [1, 2, 5, 8, 9, 6]
totalProduct = foldl (*) 1 array

And it’s good because you don’t need indeces because indeces are evil. And they have to do with numbers and I hate numbers.

It’s also nice bceause you have this abstraction of turn an array into a single value. This pattern appears countless times in coding, and it’s a more useful abstraction as opposed to the loop, which is so generic it could basicall mean anything. It’s a nice compromise between between powerful enough that is can be used for many purposes, while not too generic, so that you still have this vague idea of accumulation.

In contrast to accumulation the other thing you do with array is turning it into a different array. In haskell, this is done with map.

array = [1, 2, 5, 8, 9, 6]
addOne x = x + 1
totalProduct = map addOne array -- is now [2, 3, 6, 9, 10, 7]

This is somethnig that you can also do in python with a list comprehension, which is the only part of python that I like. Not true, I like other parts of python, but python gets too much love these days, and it should get some more hate. Please spread more hate. Just one dollar a day can make a difference, and discourage some noob from writing spaghetti.

Anyway, another great advantage of this is that you don’t have to press tab, which is really important if your tab button is broken. You could not write with tabs in C, but then you will get beat up by Kennis Ritchie and Richard Kennie himself. (Those are iventors of the C language, that’s why it’s called K&R C).

I would give the example in C, but if I write more C code I’m literally going to jump off a building.

5. Conclusion

In this article, we learned how for loops are a vessel of Satan, while functional programming is like manna from God. When the judgement day comes, God will seperate functional programmers from the imperative programmers, and the functional programmers will go to paradise, while the imperative programmers will be forced to an eternity of programming in C++.

Thank you for coming to my blog. If you have any criticism or feedback, please keep them to yourself and go commit die. Bye!

Author: John Wang

Created: 2023-01-18 Wed 21:14