7 ms·
They're simple loops. You don't need to copy and paste, you just write them out because it's just ridiculously simple logic. Just like you don't copy and paste
by NateDad 12y ago
They're simple loops. You don't need to copy and paste, you just write them out because it's just ridiculously simple logic. Just like you don't copy and paste if statements.
- nine_k 12y agoRidiculously simple and wordy. Exactly the stuff the computer should do for me.
- jasonkostempski 12y agoI think editors solve that problem pretty well. I usually only have to type something like "fo"<TAB> part of my collection name and another <TAB> or 2 before I get down to business, no matter what language I'm using.
- nine_k 12y agoYou only write source code once. You read and edit it many times, and your colleagues, users of your library, etc, read it many more times. The longer the piece of code one has to read, the easier it is to read it incorrectly, miss a bug, or introduce a bug.
- NateDad 12y agoThis is just not true. Many simple lines are easier to read than fewer more complex lines. It's hard to miss a bug in x = x + 1 foo[x] But easier to miss a bug in foo[x++]
- kasey_junk 12y agoAs an industry we have no objective measures for what makes code "better", so in many ways these debates are pointless. That said, I'd add 3 points to this particular thread: 1) You cherry picked one of the most confusing uses of operators (and sources of bugs) that we have. If it weren't so ingrained in our educations/history (and so useful for old fashioned looping semantics) I think we all would have moved on from ++ syntax a long time ago. 2) As flawed as it is, it is a well studied phenomenon that LoC is nearly the only measurable statistic we have that is predictive of error rates (that is higher LoC solutions tend to have higher bug counts). 3) The bigger point about looping constructs isn't about LoC in any case. It is de-coupling 2 different areas of code responsibility. One is the mechanics of iteration and the other is what to do on each event. At the end of the day most looping constructs end up being sugar around while loops anyway, so the reductionist argument is all of it is unnecessary complication, just do everything in a while loop.
- Retra 12y ago> As an industry we have no objective measures for what makes code "better", so in many ways these debates are pointless. I don't know why people keep saying this. We write code to solve problems. The best code solves the most problems in the most correct and efficient ways. Regardless of your measure of efficiency, if someone cannot quickly tell if your code is correct, does what is intended, and does or does not apply to their problem, then the code isn't good. That's your measure: Can the people who want to solve the problem you are trying to solve efficiently identify, evaluate, and employ your attempted solution?
- kasey_junk 12y agoNothing in your measure can actually be "measured". That is given 2 different solutions to the same problem, how do you determine which is better? The reason people keep saying that we don't have any measures that do this, is that it is a bafflingly tricky problem that has been studied for decades with hardly any forward progress, and lies at the heart of most of the big issues in our industry.
- Retra 12y agoWhat makes you think it can't be measured? Just because we don't have the infrastructure to do it doesn't mean it can't be done. >The reason people keep saying that we don't have any measures that do this, is that it is a bafflingly tricky problem that has been studied for decades with hardly any forward progress And what if I had a solution? How does this comment help anything? What do you think the difference is between unsolved and unsolvable, and how does your reaction not foolishly apply to both? How would you recognize progress in the context of my post? Here's a Haskell factorial function: -- Basic factorial function. fac :: Integer -> Integer fac n = product [1..n] Here's an attempt at a factorial function in another language: .r $15265f38a [] (44) ; dup n + offset; _ Which is better code? Do they both compute a factorial? Do they both terminate? How did you determine this without using any 'measurable' data?
- 12y ago
- __david__ 12y ago> They're simple loops. Unless you need a do/while loop. Then you're SOL.
- rjberry 12y agoAll loops encode simple logic? I don't think that's true. Either way, a very good reason for not using loops is to make code more readable. If I see a loop I have to run it inside my head to figure out what the intent is, and if there's multiple things going on, that can take time. If I see a 'map' I think "right, this is tranforming every element in this list in this way"; if I see a filter, I think "right, this is removing elements in this list that don't satisfy this property", if I see a groupBy, I think "right, this is grouping elements in this list by this property", etc., etc. Code isn't only more succinct, it's more human friendly.
- ominous_prime 12y agoExpanding a map to a for loop is very simple. Yes it removes a shortcut available when writing code, but when reading code I can consume that simple chunk of logic in one mental bite just as easily as I can a call to map.
- rjberry 12y agoSure ... but if a loop is effectively doing a map, a filter, and a bunch of other operations all at once? It's a lot quicker to figure out what's going on if it's been written with combinators (once you're familiar with them) than if it's the vanilla loop.
- dangerlibrary 12y agoIt can be a lot less performant to chain several combinators.
- rjberry 12y agoIf we assume the operations we're talking about take time linear in proportion to the list, you've just gone from a * n time to b * n time, where b > a. Both of these are still O(n) in Big O notation, which drops constants, because constants unless they're very large or n is extremely large, tend to have relatively little effect on the running time of an algorithm. Choosing to write more verbose, difficult to decipher, difficult to maintain code, under the claim that it will perform better, is not a good thing: "premature optimisation is the root of all evil". In practice, if this becomes an issue (which you find out through benchmarking once you know there is a perf issue), most modern languages offer an easy way to swap out your data-structure for a lazily evaluated one, which would then perform the operations in one pass. Languages like Haskell or Clojure are lazy to begin with, so do this by default.