I was sitting with some friends the other week and a question came up. Someone asked, “so, when did you last write a for-loop?” We all chimed in, one after another, and the answers varied. Some of us had written fors earlier in the day; others, the previous week. Some of my friends hadn’t written a for in months. And, no, it wasn’t because they’d left programming, it was because they were working in languages where you either don’t have fors or you don’t have to use them often… languages like Ruby, Smalltalk, OCaml, and Haskell.
Well, more power to them. I work in C, C++, and Java periodically. For-loops will always be a part of C. In C++, we you can avoid fors with algorithms and functors (although the syntax is a bit wild), but in Java, you’re still stuck with them unless you opt for the Apache collections library or some homegrown solution. Yes, there’s talk about adding closures to Java, but it’s not there yet.
There’s something very annoying about writing a for. For one thing, you have to deal with a lot of detail that is really “off the side” of what you want to do. If you want to iterate an array in C, you can do this:
for(int n = 0; n < size; ++n)
sum += elements [n];
Isn’t it ridiculous that most of the complexity is in the first line, rather than the second? It’s all bookkeeping.
Isn’t it even more ridiculous that we’ve been doing this for years? And, sadly, it’s not because we haven’t tried to abstract our way out of it. Since the beginning of “structured programming” people have looked into ways to make iteration less onerous. I remember Pascal and Ada with their “upto”s and “downtos”.. and there was the CLU language, which introduced the concept of an iterator, which was great, but then we had to live with this for years in Java:
for (Iterator it = orders.iterator(); it.hasNext(); ) {
Order order = (Order)it.next();
…
}
It was just insane. And, yes, the for syntax introduced in Java 5 is nicer, but, really, just give me a block:
orders.each { | order | ... }
So we're moving forward. People are moving towards blocks and closures, but why did it take so long?
Part of it, I think is a historical fear of inefficiency. For the longest while, the idea of using a block in the context of iteration was scary for many people. There's more indirection. And, regardless of whether it was slower, it looked slower. Another part, I think, was a fear among language designers that the vast majority of programmers wouldn't be able to handle blocks or that they would be put off by them. And I think that today we can say that that is obviously wrong. It's just a shame that it took so long to figure out.
So, if I run into those same friends in five years and we have the same conversation, I wonder what the answers will be? Will any of us still be writing fors? Only the C folks.. that's my bet.

Comments (23)
Reg Braithwaite has a post about the more general idea here, of separating the accidental and inherent difficulties, called Economizing can be penny-wise and pound foolish. His system of highlighting code in green, yellow, and red is handy:
"If you don't understand what something does, mark it in red. If you understand it, but it has everything to do with the accidental difficulty of the implementation and nothing to do with the inherent difficulty of the problem, mark it in yellow. And finally, if something seems to express the problem and its solution fairly directly in an manner you understand, mark it in green.
What could be simpler? We want more green, less yellow, and absolutely no red in our programs."
Posted by Dan Bernier | October 18, 2007 11:04 AM
But don't forget that C and C++ come with CPP, which can get you out of (and into) all kinds of trouble. Trolltech's C++ library Qt, for example, has a nice foreach macro:
foreach( Order& order, orderList ) { ... }I believe Boost has something similar as well.
Posted by Chouser | October 18, 2007 11:40 AM
What about:
for(Order order : orders)
{
...
}
Best new java feature ;-)
Posted by Felix | October 18, 2007 3:43 PM
Felix -- the For Order Order Orders reminds me of a post by David Heinemeier Hansson where he smiled at this code:
http://www.loudthinking.com/arc/2006_04.html
Posted by slothbear | October 18, 2007 10:15 PM
In D, you can avoid the for loop because it has built in dynamic arrays and the keyword foreach. D is designed to be a replacement of C++. In C++ (using the STL), instead of :
vector int_list;
// initialization
std::iterator a;
for (a = int_list.begin(); a != int_list.end(); a++)
{
}
in D, you write (arguably the equivalent):
int[] int_list;
// initialization
foreach (a; int_list)
{
}
Posted by bosco | October 19, 2007 12:25 AM
Using boost::foreach, you can do, in C++:
// Don't use the ugly uppercase identifier:
#define foreach BOOST_FOREACH
foreach (a,list) {
...
}
Works with anything that supports iterators.
Posted by w-g | October 19, 2007 4:29 AM
Not exactly true -- in Python, going through objects (exposing the matching API) is mostly done by a for. ;)
But I agree with you that for-loops (as in C) aren't exactly brilliant. As you've shown in the example above, you are often not even interested in the index -- but still have to keep it around. I consider Python's (and Ruby's or any language that supports this concept of iteration) way of going through the sequence (or iterable) much cleaner, concise and problem-oriented.
P.S. As far as I can backtrace it, Python has its for statement for at least 10 years, dating back to Python 1.5 (published in early 1998).
Posted by stargaming | October 19, 2007 6:33 AM
This isn't new at all. "Any loop that steps only one variable is useless" -- see "The Evolution of Lisp". http://article.gmane.org/gmane.comp.lang.groovy.jsr/1577
Posted by Martin Dengler | October 19, 2007 8:04 AM
I still use for loops often in Python. The iterator construct is a base type in the language; hiding most of the implementation from the programmer if they don't need it.
It's easy to read and consider:
for item in my_list:
...
for item in get_items():
# A generator, oh my!
...
clean_list = [some_func(x) for x in some_list]
# you can add an if statement on the end too
Perhaps Python is one of the few languages to consider the implementation of iterators as a base-type rather than an after-thought.
These days I find lambdas and map() more useful, but I still find the venerable for loop very easy to understand when the proper idiom is used.
Python ftw. :)
Posted by James | October 19, 2007 9:02 AM
There are other, simpler ways of solving this, like functions as first-class objects. Lisp has supported this for decades already. Here's a Python solution following that. (The >>> is the Python interpreter prompt; lines without it are the interpreter showing the result from the previous line.)
Not only is this a one-liner, it's also a simple and straightforward one-liner. This is also highly paralellizable, as Google's MapReduce framework shows. So there's no question that this kind of approach is important, and not just to simplify life for the developer.
Posted by Lars Marius Garshol | October 19, 2007 9:49 AM
This is one thing I like about Groovy, when you define a method with a closure as the last parameter like this:
void foo( int bar, String baz, Closure fn )
{
...
}
you can call this in Groovy code like this:
myobject.foo( 100, "Hello" ) { spam -> ... }
This makes extending your objects quite easy!
-David
Posted by DavidM | October 19, 2007 9:52 AM
I was once lamenting about how C didn't have an concise collection-like thing that allowed me to write for/each loops like I do in Ruby, and Greg Kroah Hartman [http://www.kroah.com] happened to be in the room at the time and said something like "But you can when you're writing Linux" (as in when writing drivers, or USB subsystems etc.).
I wish I had asked him about this more, but does anyone know more about this? Is there magical preprocessing going on, or CPP-like collections included in certain Linux-dev headers?
Posted by Edward Ocampo-Gooding | October 19, 2007 11:21 AM
I guess maybe you have to use Ruby to understand it's advantage, but ever example I've seen looks less readable (more like Perl) than the equivalent Python.
The example in the article is a good example. What is the advantage of:
orders.each { | order | ... }over:
Are the two effectively equivalent?
The lack of punctuation in the python makes it vastly more readable in my opinion.
Posted by Anonymous | October 19, 2007 12:29 PM
I think that you're selling short the power of C's construct. Specifically, I use "for" loops more frequently to iterate over lists than I do arrays, e.g.:
for (elem = head; elem != NULL; elem = elem->e_next) { ... }To me, C's construct is spartan but tight and efficient -- I don't have to guess about the code that's going to be generated, and the construct has no implicit space or time overhead. On the other hand, Ruby and the block/closure crowd are nice to look at, easy to code, and perfect when performance and footprint will never matter. To me, this puts Java and especially C++ in an awkward middle ground that has the worst of all worlds: an arcane interface and suboptimal performance.
Posted by Bryan Cantrill | October 19, 2007 1:15 PM
Go Python for ease of use and simplicity!!!!!
Posted by Al | October 19, 2007 2:27 PM
Javascript in moz browsers:
for each (item in object) {}
also:
array.forEach(callback[, thisObject]);
Posted by Dan Sickles | October 19, 2007 3:20 PM
It's been a while, but I seem to recall that the Linux kernel uses some pretty neat macros that operate on simple data structures (like linked or doubly linked lists). No pre-processing, just plain macros. If you're interested, I suggest you either look into the header files or get a book on the kernel ("Linux Kernel Development" is pretty good IMO).
Posted by Lea Wiemann | October 19, 2007 6:28 PM
In Ruby the Python like for loop is still there. It is just syntactic sugar for the Smalltalk like variant.
Python:
for order in orders: do_something(order)Ruby:
for order in orders do do_something(order) endwhich is syntactically rewritten to:
orders.each do |order| do_something(order) endwhich is just the same as:
orders.each {|order| do_something(order) }Lua:
for order in pairs(order) do do_something(order) endSmalltalk:
Scheme:
(for-each (lambda (order) (do-something order)) orders)Lisp:
Of course there are many, many more variants in Scheme, Lisp, etc. but they won't add anything to the picture here.
It is all the same, except the index is not there,
which is not that big of an improvement, but significant enough to matter. Besides, iterating with pointers in C, like shown above, is barely different from the above examples.
I don't mind for loops (or recursion for that matter) at all, although more often I find map and other catamorphisms like fold (reduce) more precise and clutter reducing. They essentially separate the loop mechanism from the work of the loop which, at least for many people, make them more abstract and difficult to read, probably just because they are not used to that level of abstraction, but that is just a habbit, like branching directly with jumps/goto is (not that there is anything wrong with that in itself), even though people today use loops.
If I am to pick on a loop mechanism that I don't find useful, it will be while for looping. It is a mostly useless construct, because it is used most often for pulling data (polling) than for actually looping. C is the exception here, but only because assignments can be embedded as is a common idiom in C.
I recall that Paul Graham actually wrote a Common Lisp macro for a while (and many others like it, named anaphoric macros) with implicit pull data (named "it"), capturing "it" on purpose in the macro ("On Lisp", pp. 189-191:
(defmacro awhile (expr &body body) `(do ((it ,expr ,expr)) (not it) (progn ,@body)))Note how "it" is captured on purpose, and can be used inside the body. This is a kind of unfold I think. the "a" prefix is a mnemonic for anaphoric, a term coined by Paul Graham.
Also as a final nitpick, I will take until over while anyday. When we terminate a loop is far more interesting than when to continue. An until/till loop is easier to read just because of that.
Loops, loops, loops...
By the way, I wrote a foreach loop just today. It will be interesting to see just how long, before I cannot remember the last time I did so.
Hmmm. I think I'd settle for having just labeled gotos with rebinding of variables and maybe a bit of syntactic sugar on top (lambda as the ultimate goto, anybody?).
Maybe it is just all a matter of syntax, but if we abstract the semantics of programs, why shouldn't we be able to choose our own syntactic abstractions (macros again) to a certain degree?
Hmmm. The whole thing quickly gets too complicated , but at least it's worth thinking about.
And now I am off topic, so I'll stop.
Posted by Dennis Decker Jensen | October 19, 2007 6:56 PM
one word:
mapM_
thread over.
Posted by Anonymous | October 19, 2007 9:10 PM
I quit using "for" loops for years now! I use c# and "foreach" exists since the version 1.0, delegates as well. I don't know why c# is not mentioned here...
Posted by Sadek Drobi | October 20, 2007 10:04 AM
Compare the following statements:
Java 5:
for(Order order : orders) { ... }
Ruby:
orders.each { | order | ... }
What's this article about again?
Anyway, Ruby's brevity is little more than encapsulating syntax with new language structures, duck typing, plus a few other semantic features.
I like and use Ruby, but this sort of "OMG it's soooo easy it must be magic" is silly.
Posted by Trevor | October 21, 2007 8:44 AM
For someone coming from an embedded software bend, I find it very comforting that the construct of the for loop in C is so verbose. It doesn't hide any of the details of what is being iterated, and the range of the iteration.
Posted by tehnyit | October 24, 2007 6:38 PM
Yeah, reduce(operator.add, list) is sort of fine, though it forces people to learn about, and import, operator.
It's be kinda cool to be able to do reduce(+, list) okay, maybe not, we don't want to turn into Perl.
Posted by Python | November 6, 2007 6:29 AM