Hacker News new | ask | show | jobs
by tpoacher 1894 days ago
I agree, but also I think this is misrepresenting the 'early return' pattern. It's more likely to be succinct and look like this instead:

    function check(x) {
        if (!test1 (x))   return false;
        if (!test2 (x))   return false;
        if (!test3 (x))   return false;
        if (!test4 (x))   return false;
        return true;
    }
In _this_ scenario, it is true that this is much more readable than:

    function check(x) {
        if (!test1 (x)) {
           return false; 
        } else if (!test2 (x)) {
           return false;
        } else if (!test3 (x)) {
           return false;
        } else if (!test4 (x)) {
           return false;
        } else {
           return true;
        }
    }
4 comments

Never ever use if without curly braces. That's one of the worst ideas of C's syntax.

Your first example would still look clean like this:

  function check(x) {
      if (!test1 (x)) { return false; }
      if (!test2 (x)) { return false; }
      if (!test3 (x)) { return false; }
      if (!test4 (x)) { return false; }
      return true;
  }
And it would be much safer from stupid copy/paste errors.
Instead of

    function check(x) {
        if (!test1 (x))   return false;
        if (!test2 (x))   return false;
        if (!test3 (x))   return false;
        if (!test4 (x))   return false;
        return true;
    }
why wouldn't you do something along the lines of

    (every (lambda (f) (funcall f x)) (list #'test1 #'test2 #'test3 #'test4a))
or whatever is the equivalent in your preferred language?
The tests are rarely that simple or regular.
Isn't that exactly the reason to put them somewhere else?
No, I just mean the actual tests might be something like:

    if (user == null) return false;
    if (IsCompleted(user)) return true;
    if (action == null) return false;
    if (value < 0 || value > 100) return false;   
You're not usually just passing a single value to a bunch of "test" functions.
Well, the way it was written, I was assuming that conditions to be satisfied had separate named predicates (although combinators could alleviate even some of these things).
Worth noting that elses don't require curly braces, which are where most of the visual noise is coming from in your example:

  function check(x) {
    if (!test1 (x))      return false; 
    else if (!test2 (x)) return false;
    else if (!test3 (x)) return false;
    else if (!test4 (x)) return false;
    else                 return true;
  }
I think this is more clear than either of the above
> Worth noting that elses don't require curly braces

True. I still think the first is clearer though. Either all tests pass, or they don't.

(also I'd be very skeptical of such an if..else ladder. Prime target for bugs.)
That code is ugly anyway, something I would have wrote in middle school... why not:

    function check(x) {
        return test1(x) && test2(x) && test3(x) && test4(x);
    }
Or, since I assume is JavaScript, just:

    const check = x => test1(x) && test2(x) && test3(x) && test4(x);
Nobody would actually write this, it's just a demonstration of the pattern at hand for the sake of discussion