TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

What's Wrong with the For Loop

87 pointsby jrheardover 13 years ago

15 comments

pmr_over 13 years ago
Is it just me or was this article entirely about lambdas and higher order functions? There wasn't a single example that captured a variable outside of the scope of the function and passed it around.<p>Lambdas by them self are incredibly useful but a closure has a lot more benefits. Your API can return functions that manipulate values through references without exposing exposing the value and giving a lot of flexibility.<p>Personally, I consider higher-order functions and lambdas convincing enough to have them added to a language, but it takes more than that to convince a broad majority that does not have much exposure to functional programming. While showing how cool you can sum things up with Haskell is certainly nice, the degree of flexibility and usability that is added to APIs is much more convincing.<p>Edit: Had to write this in a hurry and now came back to make it more substantial.
评论 #3626975 未加载
评论 #3626399 未加载
评论 #3626452 未加载
评论 #3626074 未加载
potatoliciousover 13 years ago
I love closures. I can't live without them.<p>And I never, ever, use them to replace a for loop. Approaching closures from the "because they can replace loops in great ways!" is IMO pretty boneheaded.<p>Let's take something from iOS land, where blocks (Obj-C closures) make my life easier than it ever has been before. If you want to hide an object, then destroy it once its hidden:<p>[UIView animateWithDuration:0.2 animations:^{ myObj.position.x += 10.0; } completion:^(BOOL finished) { [myObj destroy]; }];<p>How would you implement this without closures? How much of a clusterfuck will it be? Will you have to install something that will poll for the animation to be finished? Will you write a big "animation manager" class that will throw around a bunch of function pointers and callbacks and marshall all of your animations for you? Will you have to declare a load of protocols and support classes just to <i>implement</i> said callbacks?<p>The biggest boon to closures, for "regular" programmers, is the <i>dramatic</i> simplification of async code.
评论 #3626710 未加载
评论 #3627947 未加载
评论 #3627426 未加载
评论 #3628815 未加载
SeoxySover 13 years ago
Arguing that closures are great because they let you replace for loops is like saying the iPhone is great because it has a better texting interface than a Nokia 3310: it's entirely missing the point.<p>What makes closures is that it opens up a whole new way of coding. Two things specifically make this possible: that they can be treated as data[1], and that they can capture local variables.<p>Closures is, for example, what makes the entire premise of OS X's Grand Central Dispatch framework possible. You can create a closure, and seamlessly execute it in a background thread, on a different core. You can build complex queues and dependencies of operations and use all cores in parallel, while keeping a very simple interface to the whole system.<p>Here's an example pulled from my toying around in Ruby, trying to implement a machine learning algorithm.<p><pre><code> thetas = gradient_descent 0.1, 10 do |theta0, theta1| J theta0, theta1, training_set end </code></pre> This code uses a gradient_descent function, and passes it a closure to find the values of theta0 and theta1 which minimize the function. It will automatically figure out how many arguments to minimize, based on the closure's `arity`. The closure captures the `training_set` variable and uses the arguments to call cost function `J`. This would not have been possible, or nearly as easy, without closures. Peruse the entire &#60;60lines code at [2].<p>Closures open up a whole new world of possibilities.<p>[1]: Most languages cannot serialize a closure, though. Lisp is pretty unique there. [2]: <a href="https://gist.github.com/48a7006e138460b65173" rel="nofollow">https://gist.github.com/48a7006e138460b65173</a>
评论 #3626382 未加载
barrkelover 13 years ago
If you want to sequentially execute a block of code with a variable that takes successive values, a for loop is probably just what you want. Nothing wrong with that.<p>If you want to process a sequence of values, and filter, aggregate etc., a for loop is probably too low-level; with judicious use of some libraries, you can work to a higher level abstraction. This is no different in C than it is in Haskell; it's just harder in C, because C is low level to start with, and doesn't have very powerful abstraction features.<p>The real risk here, I think, is using the wrong language to solve a set of problems, rather than using the wrong feature.
lihaoyiover 13 years ago
There's nothing wrong with a for-loop. Nothing at all. Using closures instead of an explicit loop is only a minor gain.<p>The real use comes when you want to perform more complex control-flow logic with different transformations. When you are working with planar undirected graphs instead of arrays, for example a HoMM3's hexagonal grid, repeatedly writing out your breadth-first-search code to do simple graph modifications/transformations gets old really fast.
评论 #3627203 未加载
RandallBrownover 13 years ago
A for loop is definitely not the place to convince people that closures are any good. A for loop is already essentially defining a block of code to be run on each item in the loop, and it's hardly very different.<p>My closure AHA! moment was writing asynchronous networking code for the iPhone. Instead of dealing with delegates and writing protocols, I could just pass it a block of code to run when the request completed. It turned a multiple file and many line design, and brought it down to just a couple of lines. It was great.
评论 #3625901 未加载
评论 #3625894 未加载
sircluelessover 13 years ago
Don't get me wrong, I love closures, but <i>all</i> of these examples are basically as miserable as the "3.times" example.<p>"Oh, hey! We can replace a for loop doing addition with a fold, with only the added conceptual complexity of ensuring that (+) is an associative operator, and making sure that we don't accidentally blow our stack by unexpectedly recursing too far because we assumed the wrong evaluation order." (Which by the way his example does.)
评论 #3626522 未加载
tikhonjover 13 years ago
I'm surprised by the hostility in the comments.<p>Also, everybody's focusing on closures, which makes sense given the article, but I think the main point is about <i>higher-order functions</i> which require first-class functions (what the author calls closures).<p>Using higher-order functions in place of loops is much like using structured programming instead of goto.<p>A for loop is just a specialized form of goto that makes what its doing more explicit, lowers spaghetti code and makes making mistakes harder.<p>A fold or a map is just a specialized form of a for loop that makes what its doing more explicit, lowers spaghetti code and makes making mistakes harder.<p>Everybody decrying the article would probably never <i>dream</i> of using gotos for control flow--structured programming is patently superior! And yet you are also reluctant to use higher-order functions.<p>I think this is a perfect realization of PG's ideas in his Blub essay.
评论 #3628152 未加载
评论 #3627921 未加载
ahelwerover 13 years ago
"Well," I said to myself as I read this article, "this wouldn't work if you had to iterate through multiple arrays simultaneously." Then I was enlightened as I realized the intended purpose of the zip function.<p>This followed by disappointment, as I was unable to experience a similar enlightenment for cases that did not have completely embarrassing data parallelism. For instance, given arrays A, B, and C, we want to set A[i] = B[i-1] + C[i+1] (with special cases at boundaries). How would you do this with the map/filter/fold primitive recursion patterns?<p>Edit: Upon thinking of it more, would slices do the trick? So, in Python:<p><pre><code> A = [0,0,0,0,0] B = [1,2,3,4,5] C = [6,7,8,9,10] A[1:-1] = map(sum, zip(B[:-2], C[2:])) </code></pre> Is there a better way to do this? I would say it is much less easy to read than A[i] = B[i-1] + C[i+1]. I would probably have to add a comment to the effect of "this is what this line is doing", which goes against the self-documenting argument.
评论 #3626445 未加载
评论 #3626543 未加载
评论 #3626365 未加载
评论 #3626362 未加载
评论 #3626447 未加载
munificentover 13 years ago
&#62; But it does highlight the key failing of for loops: they conflate three separate kinds of operations -- filtering, reduction and transformation.<p>Unsurprising for a Haskeller, but he forgot the fourth and likely most common use of for loops: iterative code that has side effects.
评论 #3627164 未加载
评论 #3628059 未加载
评论 #3627191 未加载
dr_rezzyover 13 years ago
Its clear, closures actually solve the problem of random array access in high level languages. You are either after 1 value or all of them. These are 2 very easily optimized access patterns. Out of bounds array access isn't a constant threat.<p>Edit: I consider loop based programming my most essential coding pattern.
jisaacstoneover 13 years ago
Turns out I don't seem to understand closures.<p>I mean I use what I think are closures in Javascript, but I thought they were to 'prevent the pollution of the global namespace' (a noble endeavor). I don't get how it relates to map, reduce(fold?) &#38; filter.
评论 #3626725 未加载
评论 #3627183 未加载
droithommeover 13 years ago
Yeah I wouldn't let that guy near any code at our company.
bwarpover 13 years ago
This is all language astronauts. There's nowt wrong with the for loop for most cases I can think of.<p>Closures are way more expensive if you include the call overhead.
评论 #3627208 未加载
jlaroccoover 13 years ago
Articles like this really make me think... that maybe the Haskell and FP people have their heads in the clouds.<p>I've played with OCaml, Haskell, Erlang, Scheme and Common Lisp, and I always end up going back to Python, C, and C++ for all of my "real" development.<p>IMO the abstractions available in the more mainstream languages are easier to understand and use in almost every case. They also perform better on existing hardware.<p>This particular article is really bad because most of its arguments are straw men.<p>For example:<p>"Instead, higher level operations like sum, prod and concat are defined in terms of folds. And your code is then written in terms of these higher-level reducing operations, making your code more concise, easier to read, easier to write, and easier to understand."<p>Building higher level abstractions from the language's lower level abstractions is basically the entire point of programming in any language. It's convenient that Haskell's library includes functions like sum, prod and concat, but it's hardly the only language including them, and it's trivial to write them correctly and reuse them in the languages without them.<p>And then he says stuff like "If you're still not worried about bugs, think about the possible typos. Then think about how often you write loops like this." Because nobody ever makes typos while using folds and closures, right?
评论 #3627863 未加载
评论 #3626800 未加载