3 ms·
> Why so much hate for loops? I don't think there's any _hate_ for loops, however, they are a very common pattern, so it's not unreasonable to argue it can be
by maest 5y ago
> Why so much hate for loops?
I don't think there's any _hate_ for loops, however, they are a very common pattern, so it's not unreasonable to argue it can be further refined/abstracted.
Most people agree that "for x in y: foo(x)" is an improvement over "for(int i=0; i<=n; i++) {foo(x)}". It's not wild to argue that "foo' x" is an improvement over "for x in y: foo(x)"
- enriquto 5y ago> Most people agree that "for x in y: foo(x)" is an improvement over "for(int i=0; i<=n; i++) {foo(x)}" Well, I don't. The second version is much clearer to me, for example, if I want to be sure about the running time of the code. Will it take one second or be instantaneous? The first example hides the length of y. I favor a programming style where all loops have clearly identifiable bounds. Using "iterators" hides these lenghts and makes the code much harder to reason about.
- the_af 5y ago> The second version is much clearer to me Clearer? Did you notice the second version contains a bug? The first version makes it easier to spot said bug, because it's more concise and with fewer parts where you could make a mistake. Note that even in this very short piece of code it's easy to miss the bug; imagine in actual loops! You have no guarantees about the running time of the code in either case, not without delving into the specifics of your programming language. > I favor a programming style where all loops have clearly identifiable bounds. Using "iterators" hides these lenghts and makes the code much harder to reason about. I find the opposite to be the case. Explicit loops with indexes make off-by-one errors likely, which is one of the most common kinds of error. It's impossible to make that kind of mistake with a foreach or map-over-this operation.
- maest 5y ago> Did you notice the second version contains a bug? Whoops - in my defence, I haven't coded in C in a very long time. I'll leave it there, since I think it makes an (unwittingly) good point.
- enriquto 5y agoThis is mostly a matter of perspective. An off by one error may go harmlessly unnoticed at worst, or trigger a harmless segmentation fault at best, in which case it's very easy to find and fix the silly problem. On the other hand, code that hides things tends to be much harder to debug, when it invariably fails. Why is my program suddenly gobbling 10GB of memory? After several hours of profiling and debugging: ah, here's this particular combination of constructors that allocates and frees a stupid amount of memory for no reason.
- the_af 5y ago> An off by one error may go harmlessly unnoticed at worst, or trigger a harmless segmentation fault at best, in which case it's very easy to find and fix the silly problem Yes, but even better if you don't write the bug to begin with. It can also fail harmfully, like failing to trigger a segfault but producing the wrong computation, resulting in sending the wrong amount of energy to the X-Ray machine, the wrong amount of money in a bank operation, firing the wrong number of missiles, etc. > code that hides things tends to be much harder to debug, when it invariably fails In the general case, I agree. In the case of foreach loops (or maps or folds) the good thing is that they are well understood abstractions, not something your fellow coworker wrote and that you must understand from scratch. They are common idioms, just like you don't debug (under normal conditions) how a for-loop with an index works internally.
- RHSeeger 5y ago> An off by one error may go harmlessly unnoticed at worst, or trigger a harmless segmentation fault at best Or be used in a remote code execution attack. So "harmless unnoticed" is FAR from the "worst" case.
- yjftsjthsd-h 5y agoYeah, I had to reread that because I'm pretty sure "silently wrong" is the worst case, and not harmlessly so; I would 100% prefer segfaults, which let me actually fix the problem or at least know something's wrong.
- Jtsummers 5y agoThe analogous for loop would have you compute n from the size of y. You still don’t know, statically, the length of the loop in that case unless you statically know the size or length of y. It has the same problem either way. Similarly, if you always know the size of n in the C style loop, then you would always know the size of y in the Python style loop. The Python loop just has the benefit of being shorter (by a line and a few tokens).
- monkpit 5y agoBoth hide the length…
- nemetroid 5y agoIf these two examples are intended as alternative versions of the same idea, the value of n would be something like y.size().
- oh_my_goodness 5y agoFolks, folks! Can we not downvote loops at least? All we want, I think, are useful tools. For goodness' sake, isn't it obvious that loops are a useful tool? Not a compulsory tool, not a forbidden tool, not a foolish tool, not obviously the correct tool in all situations, possibly not something that needs to be mainstream in every work flow? Sure, all of those. But ... we're downvoting loops now?