What’s so Wrong About Looping?

It seems there is a modern-day vendetta  in the programming community against the humble loop. It started with iterators, and then the C++ template library, where collections were traversed by a function and you had to plug in your little callback for the processing done with each item. LINQ came along and furthered the nefarious ends of SQL to eliminate iteration in all its forms except those implemented by the query engine. And finally, functional programming has come along and reduced all looping to recursion with lambda functions.

And what has the poor for-loop (or while-loop or do-loop, etc.) done to deserve such treatment?

Seriously. That’s not a rhetorical question.

I played along in the early days. But then I noticed that there were two conditions that kept recurring and forced me to write the for-loop myself. The first condition was when I needed to know the index of the current item (or in the case of searches, of the item found). Trivial to know with a for-loop iterating over an index; with iterators you needed an extra counter variable. Functional programming would deny the need to ever use an indexer. Cute.

The second condition was early exit. Often when looping — whether searching for something or doing some kind of accumulated calculation — you want to exit when a certain condition is hit. Again, trivial if you are writing the for-loop yourself; difficult if you abrogate the loop to some other agent’s control.

And what have we gained by avoiding the for-loop? We’ve saved a line of boilerplate code:

for (i = 0; i < list.Length; i++)

Ok. That is a small savings in effort. But does it justify the huge loss of control? It’s easy to read, easy to understand, easy to debug — there is nothing hidden in it. And it is under your full control. And I find that with the other looping constructs that I miss the syntactic marker that says “this code is dealing with many items and might not scale!”

Now I wouldn’t be so foolish as to suggest that iterators, callbacks, lambdas, and LINQ don’t all have their places. Certainly there are circumstances where the value of the expressiveness of these other constructs is truly compelling. But that is a far cry from implying that loops are to be avoided at all costs as often seems to be the case in the blogosphere and the ridiculous world of “best practices”.

What I’m arguing for is clarity. I’m not arguing against expressiveness or conciseness, but I most definitely prioritize clarity over them. So when trying to figure out how to code a collection operation of any type, don’t forget the humble loop.

Advertisements

About jeffkotula

Software engineer, musician, and so on...
This entry was posted in Coding, Software and tagged , , . Bookmark the permalink.

3 Responses to What’s so Wrong About Looping?

  1. At first was dumbfounded by the IEnumerable.ForEach() defined in my code base, but a couple of times it has been kinda nice to use. Have seen some egregious misuses of it though.
    // Acceptable
    Collection.ForEach(obj => obj.Start());
    // Mostly since you can then easily change it to:
    Parallel.ForEach(Collection, obj => obj.Start());
    // The following should be considered a compile error.
    Collection.ForEach(obj =>
    {
    // 20 LOC removed for clarity in blog comment.
    });

  2. jeffkotula says:

    Modifying while iterating: Actually, simple index-based looping works better than encapsulated iterators. Callbacks are probably a wash.

    Vectorizing: Recognizing the loops is easy — parallelizing compilers have been doing that since I was in college (so a _long_ time). The hard part is analyzing the inputs, outputs, and side-effects to determine if a loop can be parallelized and then whether or not it is worth it.

    (Thanks for the comments Matt 🙂

  3. Loops work great for constructs with random access, and where figuring out Length has O(1) cost.

    They work less well, when you’re modifying the construct, as you’re iterating.

    They work less well when the members that you’re iterating over need to be computed dynamically.

    In the vectorization world, they’re a lousy way to express intent, when you could be parallelizing.

    But yeah, I’m with you – when you can use a for-loop, you shouldn’t be afraid to.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s