That word, closure. You keep using it, but I do not think it means what you think it means.<p>A closure is an runtime structure used to implement static scope of locally-defined first-class functions. Closures allow locally-defined functions to "remember" variable bindings in their enclosing scope.<p>Beside that you can implement this feature WITHOUT closures (e.g. source rewriting), none of the examples presented actually require static scope!!<p>It boggles my mind that programmers can have such strong opinions on language features <i>without actually knowing what they're called</i>.
"But it does highlight the key failing of for loops: they conflate three separate kinds of operations -- filtering, reduction and transformation."<p>There's actually four kinds of operations: filtering, reduction, transformation, and <i>good Lord man what the hell are you doing with the loop index? did it just go negative? It did! Why? And it still works‽</i>, which is actually quite hard to simulate with functional programming. Fortunately.
Colour me stupid, but in the article it gives this code as having some horrible hard to find bug:<p><pre><code> String s = "";
for (int i = 0; i < args.length; i++) {
s += array[i];
}
</code></pre>
Now, as soon as I looked at that I immediately thought "well, they're not putting anything in between the params when they concatenate them", e.g. I would expect to see:<p><pre><code> s += array[i] + "\t";
</code></pre>
(or a comma or newline instead of a tab)<p>My next thought was "what happens if there are no args?" E.g. args.length returns 0, and they try to access the first element in the list (due to heritage from c pointers we start counting at 0) which is the 'zeroth' one, which doesn't exist... it should throw an array out of bounds exception.<p>-----<p>The reason I ask, is that based on the comments, the people reading the blog think the problem is in the operator overloading. Are they expecting this iteration through the args list to <i>sum</i> the args, and then assign the sum to the string?<p>If so, then I don't see how the bug could remain undetected:<p><i>"it could take weeks to get a bug report, and weeks more to get a fix ready"</i><p>Whereas in the unlikey event that I'm right, I <i>still</i> don't see how it would be hard to fix?<p>What am I missing?
I feel this post is more an argument for first class functions than closures. It is true that much of the usefulness of first class functions is lost without closures, so having useful first class function almost necessitates (though does not guarantee) closures. But in none of the examples is the key attribute of closing over free variables emphasized, which is the powerful and <i>dangerous</i> part.<p>A simple example showing the usefulness of inner functions might have been more pertinent to the term closure IMO.
OK,<p>Let's imagine there are two kinds of language/program bugs.<p>1) A given expression does not mean what you think it means. 2) A given series of expression all mean what you think they mean but the combination of them isn't what you think it should be.<p>I would submit that bug type #2 is the main sort of bug that's going to bite you and bug type #1 is relatively benign (if occasionally infuriating). Especially, even in language with obscure syntax and hairy ambiguity, you can pepper your code with asserts and track down your problem reasonably quickly.<p>I have been assure that functional programming does help with bug #2. I would love some detailed blog post akin to this which says how.<p>This article seems to deal entirely with bug type #1. Show me how functional programming deals with bug type #2.
Heh, all of these points could easily be applied to Python as well. All the concepts are there in addition to the for loop. It's nice how you can do a lot of <i>functional</i> programming in Python with these simple tools (map, filter and reduce (Haskell's foldl).<p>I wonder why there aren't more people advocating the use of these functions in Python programs instead of for loops.
You can execute loop in your head just by reading it line by line. Token by token. With other solutions you need to know other things to determine what goes inside and believe it is actually what you want it to be. Loops ar flat, explicit and versatile. I think that is the reason behind their popularity.