Hacker News new | past | comments | ask | show | jobs | submit login

How is the for-loop any better than good ol' GOTO?



In numbered-lines code you can’t see the start of a goto loop. In labeled-lines code it’s not that hard to infer that it is a jump target, but having a condition/iterator in one place is an obvious benefit.

That said, I believe most people who “boo GOTO” never actually used it to make sense of what could be wrong with it and how it feels really.

Anyway, I think that this analogy(?) is confusing and makes no sense.


Why is anything better than GOTO?

You use GOTO all the time, even if it's wrapped in an abstraction that makes its intentions less clear.


Conceptually, `for` loop is just syntactic sugar - it simplifies certain action, not makes it more difficult.


Conceptually, the `map` function is just syntactic sugar for `for` loops, and it's also meant to simplify actions. There are functional equivalents to many small patterns of code that occur often - for instance

    lst = []
    for element in range(10):
        lst.append(element * 2)
Is a very common pattern, that can be expressed with less typing (and less mental overhead, when you become used to it) by

    lst = list(map(lambda x: x * 2, range(10)))
Similarly, another very common mini-pattern is

    total = 0
    for el in range(10):
        total += 3 * el
Which can be more swiftly expressed by

    total = reduce(lambda acc, el: acc + 3 * el, range(10))
    
These examples are trivial, but once you start using these higher level syntactic sugar-like constructs, you often find that code tends to fit together more nicely and in ways that make more sense, even if only because you used a filter operation before the map instead of writing another level of nested `if` statements inside a loop body. Code gets easier to follow, not unlike how it's easier to reason about the behavior of a `for` loop than it is to keep a bunch of `goto`s in your mental model of what the code does while at the same time thinking about whether the business logic part of it makes sense.


Tbh, I get your imperative examples instantly but my mind struggles to autograsp these multilevel functional parts like list(map(lambda. Too much noise, I have to think through it to get it.

I’d prefer a loop with ifs and continues/breaks.

It may be a lack of experience or habit, but then I can write code like that (and worse), and it doesn’t make any sense to me. Don’t get me wrong, not that I refuse to use maps or filters or folds, but not that I want to make a whole program of them either. They have their place where factoring-out a block of code feels stupid, but if I had something like:

  [1, 2, for (x of xs) {
    if (cond) {emit x}
  }]
I’d never bother with these function-al things. It’s not FP that is rich, it’s a traditional imperative syntax that sucks. Paradigm shift is not equal to usage out of [in]convenience.


> Tbh, I get your imperative examples instantly but my mind struggles to autograsp these multilevel functional parts like list(map(lambda. Too much noise, I have to think through it to get it.

That's exactly why most FP languages have pipe operator, so it's incredibly easy to read.

  lst = range(10)
         | map(fn x -> x * 2 end)
         | map(etc...)
or

  total = range(10)
         | reduce(0, fn elem, acc -> acc + (elem * 3) end)


That doesn’t change much for my read ability. It even reads more imperatively, like: I take a range of 0 to 10, map it over x * 2, map it over… What do I get? A mapping? Maybe?

Meanwhile, a for loop is straightforward, you go from 0 to 10 and append a double or add a triple of x to an accumulator. I appended/added them, that’s what I get. It’s like my brain somehow follows {} scopes and understands their local envs with no effort.

If this syntactic style works for you without this friction, nice. But it doesn’t work for everyone and I suspect that this FP/PP is biased by this effect at both sides.


> What do I get? A mapping? Maybe?

A mapped list/enumerable it was originally given. You don't think what you get when you add two numbers, don't you? Language just works certain way. Not understanding a simple building block of a language isn't a valid argument against it. All you essentially say is that you got so used to OOP concepts that anything else is hard to read. And it's ok, it's the same way for everyone... But it's not a valid argument to say that "fUnCtIoNAL bAd". The whole thing here boils down to what you already said - lack of experience.

My honest advice is - try to learn one functional language, like honestly learn and understand it, try writing something with it. It really does expand horizons.


> I can write code like that (and worse), and it doesn’t make any sense to me

I'm learning FP and I see value with writing code with map, reduce etc as those are expressions instead of statements. Expressions guarantee you have a result of particular type (with possible side effects if you prefer), but statements DO side effects. The loop may or may not insert some value into resulting list because some branching happened or you forgot some else condition, with map you guarantee you get same number of objects of particular type back.

Plus that enables composition (like in C# LINQ) - by not extending some loop with different kind of responsibilities but just passing result to next function that modifies/filters the result.

https://fsharpforfunandprofit.com/posts/expressions-vs-state...


    [1, 2, for (x of xs) {
      if (cond) {emit x}
    }]
What are 1 and 2 doing? What is emit? Where does x go ?

Is the above code just:

    filter cond xs

?


It results into [1, 2, …(some xs satisfying cond)]. Emit does just that - emit another value into a context where for-expr was used. It emits some of x-es into that array literal.

filter cond xs

More like 1:2:filter cond xs.


For what its worth, the pythonic solution is

  lst  = [x * 2 for x in range(10)]


Indeed! I started programming in GW-BASIC when I was 13. IF and GOTO was all I needed! FOR, FUNCTION, ... why was it there?




Consider applying for YC's W25 batch! Applications are open till Nov 12.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: