The Foreach Inconsistency

It is interesting that most programming languages have almost identical syntax for the most commonly used set of flow of control statements. There are variations of course, but for the most part the if/else blocks, and the for, while and do loops are almost identical no matter what you use. It is actually quite surprising that the for loop is this consistent as it has the most complex of all of these statement. Yet you can jump from C to D to Java to C# to Perl to PHP and the syntax remains virtually the same. It is always variation on the following theme:

for(declare iterator; evaluate condition; increment)

It might be because all these languages try to mimic each others common features for a reason. Or it might be because the for loop is by far the most popular loop out there. If you don’t believe me look back on some code you wrote recently. I can guarantee you that the keyword for will show up much more frequently than a while or a do. For that matter, it seems to me that the do loops seem to be the least favored breed out there.

What is interesting however is that while all these languages have an identical syntax for the for loop, their take on the related foreach loop varies greatly. Everyone seems to be writing it differently. I mean look at this:

D:

foreach(element; array) {
  // do something to item
}

Java:

for (Object element: array)
	// do something

Javascript:

for (element in array)
	// do something

VB .NET:

For Each element In array
 ' do something
Next element

C#:

foreach (object element in array)
	// do something

PHP:

foreach ($array as $element)
	// do something

Perl:

foreach $element (@array)
	# do something

Python:

for element in array
	# do something

Ruby:

array.each do |element|
	# do something 
end

It is a mess. Some languages use the foreach keyword, while others simply add functionality to the standard for loop. Some like Python and Ruby completely do away with the standard counting loop and use the for … in … syntax to do all looping. The in keyword seems to be relatively popular but once again, not everyone likes it. There is even no consistence as to whether the collection/set should be specified before or after the temporary element.

Since I tend to jump between languages a lot lately, I’m perpetually confused by the foreach loops. I end up looking it up every other day because I keep forgetting which one is which. I keep putting the element outside the parens in PHP, I use the as keyword in Perl and etc. I never really had to look up a while loop in a language before – they all work pretty much the same. But it almost seems as if the foreach loop was THE feature which you use to show the world how your language is clever and superior. It’s like a contest really. My foreach is better than yours!

There is nothing we can do now. We already have all these different ways of expressing this loop floating out there. But perhaps we could try to navigate towards some common ground here. Personally I think that the foreach(element in array) syntax is possibly most readable one out there. I imagine that Java and C# folks are shuddering at the sight of that superfluous in keyword in there but for me it really helps. This is the way I would expect it to be done – put the element first, the array reference second and have it read almost English like. For each element in the array do this. How does the PHP version sound when you try to read it? For each array as element? What does that mean. Come on people, the foreach-in version wins on readability. But then again maybe it’s just me. Maybe I’m suffering from the “my foreach loop is better” syndrome too!

[tags]for, foreach, java, python, ruby, perl, php, programming languages[/tags]

This entry was posted in programming. Bookmark the permalink.



4 Responses to The Foreach Inconsistency

  1. Ian Clifton UNITED STATES Mozilla Firefox Ubuntu Linux says:

    A syntax that reads “For each element in array” makes the most sense for readability when dealing with a simple example. The problem is that the foreach construct might be able to do more than that (or that the concept of an “array” is sometimes different from language to language).

    For instance: foreach ($array as $key => $value) with PHP would maybe be translated as “For each (element in) $array (use it) as $key with $value” or something like that. The good thing is that the format is consistent with how arrays are assigned with key/value pairs. I’m not sure if there is a way of writing that in code in a way that can logically/easily be read as English (without making it excessively verbose).

    The other thought is whether the goal is really to make it “readable” in the English sense or readable in a different, logical sense. For instance, think of a nested foreach. In a language that specifies array then element, you could essentially say that you are taking an array, getting an element from that (which is also an array), and getting an element from it. In other words, least specific to most specific. If element is specified before array, you end up taking an element (which is also an array) from an array and then taking an element from the first element (or is it first array?).

    I’m not sure if I am making any sense, so maybe we should take it away from coding. Giving a thief directions: “In the parking garage, locate every car. In each car, open the ashtray. In each ashtray take the money.” The alternative: “Locate every car in the parking garage. Open the ashtray in each car. Take the money in each ashtray.”

    Reply  |  Quote
  2. Luke Maciak UNITED STATES Mozilla Firefox Ubuntu Linux Terminalist says:

    Well, PHP could easily do:

    foreach ($key=>$element in $array)

    Which could be read as “for each key/element pair in array” or something like that. Again, I’m not saying this is the best possible syntax. I’m just saying I like that one. PHP and Perl examples are perfectly logical but not as readable.

    Ruby example is elegant (each being a method) but it suffers from the “WTF is this shit” problem – because unless you used Smalltalk you probably won’t recognize the |element| notation. But arguably it is the smarter, cooler way of doing things:

    (1..10).each {|i| puts i}

    Naturally you could still do:

    for i in (1..10) puts i end

    But why would you want to do that if each collection type object has an each method defined.

    I’m not saying every language should conform to the same syntax for this type of loop. I’m just looking for some sort of consistency where possible.

    If we would want to follow the PHP like convention of using the as keyword I wouldn’t cry either. :) As long as it is consistent I can learn to live with it.

    Reply  |  Quote
  3. Ian Clifton UNITED STATES Mozilla Firefox Mac OS says:

    Your PHP example works for me, but you just broke all my scripts ;) Actually, they could switch to that and allow both forms based on the presence of “in” or “as” and avoid breaking anything.

    I agree, it’s really just about consistency, but each language somehow wants to prove itself, as you were saying. The “as” word in PHP makes some sense in that foreach loops are creating new variables and setting their values according to the array (unless you pass by reference). Essentially, you are dealing with the value as a new variable. It wouldn’t make (as much) sense in a context where you are always dealing with references.

    I like every array and object having an “each” method. Maybe it’s not quite as readable (in English), but it makes sense in coding terms. Perhaps it can use “as” (e.g., “array.each as element”) and be as simple as that. I think our biggest problem is that we base programming on English and English is inconsistent.

    while array be havin parts
        # do stuff
    Reply  |  Quote
  4. Luke Maciak UNITED STATES Mozilla Firefox Windows Terminalist says:

    LOL! The street language cracked me up!

    Reply  |  Quote

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>