Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

   return rawData && rawData.length > 1 ? rawData.map((item) => item) : []
In many other cases, I would use a result variable. It's more expressive and more importantly you can move that code (the result variable may become just another variable in a bigger function). (note that in many programming language like lisp or haskell you wouldn't need the result variable because everything is an expression) Granted, it looks like no big deal in many many spots. Until it is, particularly at scale when you can't refactor anything because everything is full of early returns.


Your program can focus on executing statements, or it can focus on evaluating expressions (or a mix of both), and I would agree there are pros and cons to each.

These small concrete examples are good to talk about. How would you rewrite the following:

    def contains_3(xs):
        """Returns True if the given list contains a 3."""
        for x in xs:
            if x == 3:
                return True
        return False
It does use an early return, but it is not long or convoluted. You could use something like `any()`, but I would never find fault with the above function or attempt to refactor it. It is as clear and efficient as possible, and uses basic language features even beginners would be familiar with.


This is how I write it:

  def contains_3(xs):
        """Returns True if the given list contains a 3."""
        found = false
        for x in xs && !found: 
            found = x == 3
        return found
Not a valid python code but who cares. Using proper python, you could write the whole thing in one line using list comprehension.

In terms of expressiveness (as much as this short example needs expressiveness), note how found is x == 3 which is what you want right. Note how the loop condition is now full. One could also note how every line is about found so you can instantly tell what lines is about found, which one is about foo or bar, if you'd picture a bigger function. Note how there is now only one condition (the loop) and not two (loop and if) (in many situations you would end up with less lines of code, surprisingly). Finally, note how DRY this is: you return x == 3, not True if x == 3 is True (there is many cases where this DRY property is more clearly visible).

This code reads like a list comprehension.

In addition to be more expressive (although, again, this is more striking on a bigger function) and movable, you can also actually write bigger functions like that which you can't with early returns (everybody agrees this is a mess).

If I'd tell you not to use jumps, you would have found that solution. Simply ban jumps from your code (find the alternative way of writing things) and you will obtain a code that will surprises you, especially in bigger functions.


> you would have found that solution

I don't think so, even after seeing your pseudo code don't see a nice way to avoid the early return. I don't understand how your for-loop / if-condition mix works, but let me try to translate it as best I can into valid Python:

    def contains_3(xs):
        found = False
        index = 0
        if not found:
            found = xs[index] == 3
            index += 1
        return found
This was honestly my first best effort attempt at creating this function without an early return. But it is wrong, it only checks if the first value of the list is 3. My opinion is that this style is more error prone (and indeed, I did create an error), and objectively there is more code and more state and thus more opportunities to get things wrong.

    def contains_3(xs):
        found = False
        index = 0
        while not found:
            found = xs[index] == 3
            index += 1
        return found
That works, but again, there is more code and more state. When reading this code I must ask myself "are they iterating over the list correctly?" and I must spend mental effort answering that question. This doesn't happen with a for-loop.

I don't understand why you keep talking about jumps in assembly code. Code which has zero early returns will still have hundreds of jumps in the assembly code.

Code that is short is good. Code that is readable is good. I don't think we'll agree on what code is more readable, but we can at least agree on which code is shorter.

As I've gained programming experience I care less and less about how individual functions are implemented and more and more about what those functions do and what they return. For something like `contains_3`, I see that it is a function with no side-effects, which returns a boolean, and wont fail (at least, wont fail in a language with type checking). This is a small simple function, and I don't care how it's implemented, it is a good function. If it becomes a problem for some reason, it is isolated and can be easily fixed in isolation.




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

Search: