News for hackers. Stuff that matters.
Re:Parse, Don't Validate (2019) by raincole on Tuesday March 07, 2023 @07:11AM (#35054456)
I don't know about this. We all have seen this kind of code:

    if(!needToDoTheThing()) return;
    
    DoTheThing();

We could have written it this way:

    if(needToDoTheThing()) {
        DoTheThing();
    }
    else {
        return;
    }
The later is closer to how pattern match looks like. But in my experience, the majority of programmers prefer early return. I regularly see people "refactor" if-else to if-early-return, but I've never seen the opposite.
Re:Parse, Don't Validate (2019) by RHSeeger on Tuesday March 07, 2023 @07:39AM (#35054651)
I prefer the former. It separates the pre-conditions from the algorithm/logic, using gate clauses. I find this makes it easier to reason about the algorithm.
Re:Parse, Don't Validate (2019) by Timon3 on Tuesday March 07, 2023 @08:26AM (#35055047)
It's much nicer, especially since it keeps the complexity down.

If you nest if/else, you'll quickly approach a point where you have to keep a complex logic tree in your head to determine which states the system could be in inside of any given branch. If you use guard clauses and return early, you'll keep this complexity down to a minimum, since the list of possible states changes linearly with your code instead of exponentially.

I know not everybody likes it, but I think this makes cyclomatic complexity an extremely valuable metric for measuring "ease-of-reading".

Re:Parse, Don't Validate (2019) by pjc50 on Tuesday March 07, 2023 @08:01AM (#35054833)
It keeps the code closer to the left. It also keeps it conceptually simpler if you can discard a bunch of "obvious" cases early on.
Re:Parse, Don't Validate (2019) by jakelazaroff on Tuesday March 07, 2023 @08:43AM (#35055215)
Yup, this is my exact rationale for preferring this too. Branches are a significant source of complexity and early returns are one way to tame it — have the “meat” of the function deal with as few invariants as possible.
Re:Parse, Don't Validate (2019) by quickthrower2 on Tuesday March 07, 2023 @11:10PM (#35065147)
The second looks a lot more elegant in Haskell though. Funny how syntax and influence choice of semantics!
Re:Parse, Don't Validate (2019) by ParetoOptimal on Tuesday March 07, 2023 @11:38PM (#35065313)
I prefer using early return in monads with guard like:

    safeDiv :: (Monad m, Alternative m) => Int -> Int -> m Int
    safeDiv x y = do
      guard (y /= 0)
      pure (x `div` y)

    main :: IO ()
    main = do
      print $ safeDiv @Maybe 1 0
      print $ safeDiv @[] 1 0
      -- print =<< safeDiv @IO 1 0 -- guard throws an error in IO
Try it out at https://play.haskell.org/saved/a6VsE3uQ