‹ BackHN Continuity

Thread

Anecdotally, programmers dislike "reduce"

175 points · 283 comments · vinhnx

  1. s-zeng · · focus · HN ↗
    Even in the world of functional programming, there's an argument to be made that `fold` is a bit of a code smell, in a similar vein as `while` being slightly smelly in an imperative code base. There's good reasons for each to be used, but they are such low level iteration primitives that you might be better off with a higher one (e.g. for loops or iterators in imperative programs; in FP you might reach for monoidic reduces (as opposed to folds where the accumulator is a different type from the list element), monadic traverses, or recursion schemes). Even though you can implement iterators or for loops in terms of while loops, you probably shouldn't, and similar for functional traversals.

    In languages like python or Java though, you don't really have access to many of the higher power functional traversals however. So that puts you into a similar kind of bind as working in a language with only while loops

    1. grebc · · focus · HN ↗
      I’ve never ever heard while described as a smell, or even slightly smelly.

      Care to explain?

      1. polonbike · · focus · HN ↗
        If you can smell it, there's something fishy in the neighborhood
      2. theamk · · focus · HN ↗
        I assume OP refers to the cases where "while" is used to re-implement existing operations... imagine finding code like this:

             i = 0
             while i != len(todo):
                 process(todo[i])
                 i = i + 1
        
        sure, there may be a good reason to implement things this way (maybe "todo" grows during iteration?), but maybe not, and then the loop should be instead simplified to:

             for value in todo:
                 process(value)
        
        (as an aside, this is exactly the case where the comments are required: "# not using for loop because todo might grow" will make it clear it's an intentional decision and not hallucination or something written from ignorance)
        1. grebc · · focus · HN ↗
          You can use iterators in a while loop like your for example, making it look as clean as the for.

          I feel like this is a case of personal preference over actual issue.

          1. adastra22 · · focus · HN ↗
            Iterative aren’t a thing in C, where that code smell notion comes from.
            1. grebc · · focus · HN ↗
              What are you even talking about.
          2. theamk · · focus · HN ↗
            you mean like that?

                todo_iter = iter(todo)
                while True:
                    try:
                        value = next(todo_iter)
                    except StopIteration:
                        break
                    process(value)
            
            or like that?

                todo_iter = iter(todo)  # Note: assume "todo" does not contain None
                while value := next(todo_iter, None):
                    process(value)
            
            I'd say neither of those are as clean as a simple for loop:

                for value in todo:
                    process(value)
            
            and yes, that's the case of a personal preference, although I'd bet a lot of Python programmers will share that preference with me. That's what "code smell" means, after all - it's not a bug which is clearly incorrect, it's a code which is best avoided based on reviewer's personal experience.
            1. grebc · · focus · HN ↗
              Your for loop is using an iterator of some kind. Just because it’s hidden in your language of choice doesn’t mean it’s not there.

              While/for can achieve the same thing, sometimes while is more practical as the steps to complete are unknown. But sure, stick your simple iterating a fixed collection as why it demonstrates while is a lesser language feature.

              1. theamk · · focus · HN ↗
                I think your arguments would be much stronger with some actual code samples.

                Usually, when the same code can be written either as range-based "for" or as a "while", the "for" will look better and have fewer possibility of bugs. If you have examples otherwise, I'd like to see them.

                (Note I am specifically talking about range-based/iterator-based "for", not the C's variant. Nor am I talking the cases where the "for" is hard to use, like when the size might change at runtime)

                1. grebc · · focus · HN ↗
                  Let's leave it there mate.

                  You're not the OP, you/me we're only guessing what he/she might've meant.

      3. d--b · · focus · HN ↗
        Probably because while is the source of many infinite loops, and because it’s sometimes faster and more rigorous to compute the length ahead of going into the loop.

        That said, I personally don’t think it’s smelly at all.

      4. [deleted] · · focus · HN ↗

        [deleted]

    2. nextaccountic · · focus · HN ↗
      > or recursion schemes

      Fold is a recursion scheme

      More complicated recursion schemes are progressively harder to read. Probably not great if you are not doing code golf

Open on Hacker News to reply ↗

Unofficial Hacker News client; not affiliated with Y Combinator.