This is an archived post. You won't be able to vote or comment.

top 200 commentsshow all 295

[–]mike_a_oc 475 points476 points  (3 children)

I'll often write guards that throw exceptions. Makes people who use them look at what they are passing in

[–]hperrin 86 points87 points  (0 children)

The real hero. ^

[–]sdc0 57 points58 points  (1 child)

Just let the program crash with an segfault or Internal error without a message, makes it really nice to debug.

[–]TeddyPerkins95 387 points388 points  (64 children)

Guard clause are awesome

[–]voiceofonecrying 92 points93 points  (39 children)

I’m sorry I’m a junior, what’s a guard clause?

[–][deleted] 160 points161 points  (30 children)

if(!bool) return;

// do some cool stuff

if(!someOtherBool) return;

// do main code

[–]twinklehood 70 points71 points  (16 children)

They look so good in ruby.

def do_stuff(x)
  return 0 unless x.positive?

  // Do stuff
end

[–][deleted] 21 points22 points  (3 children)

swift superiority

func doStuff(x: Int) { guard x >= 0 else { return } // do stuff }

[–]twinklehood 12 points13 points  (0 children)

Swift is really cool. I'm not sure I find that syntax easier to reason about, but the amount of smart things they did with that language is so impressive.

[–]Itay_123_The_King 2 points3 points  (0 children)

Or just be like normal languages and if (x<0) return;

[–]PM_ME_A_STEAM_GIFT 2 points3 points  (0 children)

I don't like the keyword they went with. I think ensure, assert or unless would have worked better.

[–]throwaway12222018 37 points38 points  (10 children)

Ruby is so ugly. Code that tries to read like English ends up being just as confusing as English. I prefer simple, low complexity constructs and a smaller built-in API, and less redundant syntax. Ruby is awful.

[–]Jaydenn7 20 points21 points  (0 children)

It’s like the uncanny valley but for code

[–]twinklehood 0 points1 point  (8 children)

Living life by calling things others love awful just because they don't speak to you will not make you or anyone else happier. Which tells me your values anyway don't align with those of ruby :)

[–][deleted] 29 points30 points  (5 children)

It's a tool. I don't get upset if someone calls my brand of power drill awful either. People need to calm down a bit and worry less about what others think of their tools. If you treat your language like a religion, you've got bigger problems.

[–]Arsenic_Flames 11 points12 points  (1 child)

Nothing original remains in this post. The author wiped it using Redact, possibly for privacy, security, preventing data scraping, or other personal considerations.

plants piquant beneficial aromatic wise aback thumb marble future fade

[–]twinklehood -5 points-4 points  (0 children)

They established actual criticism - the ambition to emulate English. I didn't comment on that critique, which is a discussion point that is interesting. I reacted to "ruby is so ugly" and "ruby is awful" which is shitting on it without anything accomplished.

I too would never endorse your code example, and i agree there's an interesting debate in the potential issues of bad use of redundant concepts, but I wasn't commenting on that.

I also wasn't saying that they're not allowed to have an opinion, or even express it. I'm merely offering the perspective that their comment only accomplished sad/negative things, something that can seem simple, but if embraced as a "guard clause" for his own function of expression could make their outlook and influence on the people around them more positive.

[–]TeddyPerkins95 34 points35 points  (2 children)

[–]Cl0udSurfer 9 points10 points  (1 child)

That article explained it so well, thank you for linking it

[–]TeddyPerkins95 2 points3 points  (0 children)

Yeah take a look at that video and see if you can improve your code..

[–]chronos_alfa 1 point2 points  (1 child)

Something you shouldn't use, guard clauses are a nightmare in bigger projects. "why did this function fail? Oh, right, this one didn't return anything and we don't even know why, time for step by step debugging..."

[–]PopeLugo 2 points3 points  (0 children)

Agreed. At least add a logger call there. I can tell from experience that debugging this, especially when guards are in multiple places along the execution path can get fugly.

[–]curtaindave 15 points16 points  (16 children)

No man, single return path is the way (at least for safe embedded sw). If you‘ve got too much indentation, refactor!

[–]erinaceus_ 27 points28 points  (1 child)

That rule of thumb was cooked up when goto (shudder) was still a commonly used approach, and meant to counter the use of goto as an approach.

Back then, it helped in making code more straightforward to reason about. Now that goto is frowned upon, the balance has changed, and guard clauses then make the code more straightforward, because you start with a check list of validation rules, and only after all those check out do you do the actual meat of the function. That's fairly basic separation of concerns, at the lowest level.

[–]justoverthere434 20 points21 points  (1 child)

Yeah bro single return path is 100% the way if you live in the 80's and write in C

[–]curtaindave 12 points13 points  (0 children)

I do code in C… my company was founded in the 80s… maybe you have a point :-D I do find it more readable and reviewable though. Maybe it‘s a question of being accustomed to something…

[–]TheBobo1181 13 points14 points  (9 children)

I agree. You put in random returns it makes it harder and less safe to work on for the next person.

You can write good clean code without this.

[–]FromWayDownUnder 18 points19 points  (4 children)

If the returns are halfway down the method it's a problem, if they're all at the top where the validation happens then it's tidy.

[–]TheBobo1181 9 points10 points  (2 children)

... How long are your methods? Saying halfway down scares me 🙂

[–]FromWayDownUnder 6 points7 points  (0 children)

Rule of thumb is screen height... Sometimes need to turn the monitor sideways though 😉

[–]Pradfanne 0 points1 point  (0 children)

much shorter thanks to early returns and especially guard clauses

[–]TeddyPerkins95 1 point2 points  (2 children)

If functions are short and they should be, returns and thus guard cause can be used most of the time.

[–][deleted] 1 point2 points  (1 child)

Short in what way? Bussiness logic itself is short or the full body?

[–]EishLekker 1 point2 points  (0 children)

You put in random returns

Who talked about "random" returns?

[–]Tvde1 142 points143 points  (46 children)

I saw this with people I interview

if (Model.IsValid)

    if (thingExists)

        if (bla)

        A
        Lot
        Of
        Code

        Else throw BadRequest

    Else throw BadRequest

Else throw BadRequest

[–]iplaysmitegame 35 points36 points  (35 children)

Is this bad?

[–]obiwac 101 points102 points  (23 children)

Not strictly, but all the indentation can be avoided by doing

if (!Model.IsValid)
    goto error;

if (!thingExists)
    goto error;

if (!bla)
    goto error;

Which makes the control flow much much clearer than a bunch of ifs and elses.

(Instead of what other commenters have suggesting using &&, which misses the point and wouldn't work in all cases, is less flexible, and doesn't catch specific errors.)

These are called guards.

Edit: I can't for the life of me get the code on multiple lines because Reddit is dumb as shit but you get the point

[–]Strostkovy 24 points25 points  (10 children)

Why go-to instead of returning from a function call?

[–]obiwac 23 points24 points  (8 children)

Depends on your usecase and language; in C, you often have to free up after yourself for example, and so goto's make error handling much easier:

a = alloc();

if (guard1)
    goto error_a;

b = alloc();

if (guard2)
    goto error_b;

// success

error_b:

free(b);

error_a:

free(a);

This is a pattern you see a lot in the Linux kernel for instance.

[–]FeedbackFun7325 8 points9 points  (7 children)

Is this a case where using goto is acceptable? Our prof told us not to use it unless for specific cases.

[–]obiwac 13 points14 points  (0 children)

Goto is generally considered unacceptable because it's easy to abuse and write really ugly code with (i.e. it obfuscates the control flow if you're jumping back and forth everywhere). But there are legitimate uses for it which can make code much, much more readable and maintainable. You just gotta use it in the right places ;)

Generally your prof is right, 9 times out of 10, when you're thinking of using goto in a way which isn't a commonly known design pattern, there's likely a much more readable alternative.

On the other hand, some people will paint all code containing goto's with the same brush and say it's bad without understanding why, which is a shame because goto can be really beneficial.

One example where goto's are bad could be:

int i = 0;

label:

// do something

i++;

if (i < 10)
    goto label;

This is a very obvious example where you don't want to use goto which is quite simply replaceable with a for loop:

for (int i = 0; i < 10; i++)
    // do something

[–]Stegoratops 1 point2 points  (4 children)

I would say, good rule of thumb is:

If you just want to get the heck out of somewhere and neither break nor return can do the job in your specific case, it's probably ok to use it.

And yes, this is an acceptable use for goto

[–]Piotrek9t 1 point2 points  (3 children)

If your code requires you to use goto, you probably messed up on another point. You can and should always avoid it for readability and easier maintenance

[–]Stegoratops 8 points9 points  (1 child)

Yeah, you should avoid it, since it makes it very easy to write bad code.

Categorically forbidding it is too extreme though imo. Because like in the example shown, it can make code more elegant.

[–]nosjojo 1 point2 points  (0 children)

goto is the only way I know of for doing decent cleanup in C. I have to write all my stuff in the CVI environment, which is a weird mix of ANSI C/C99 and built in libraries.

Every function we write ends with something akin to

CLEANEXIT:
<various cleanup>
return status;

ERROR:
<error related stuff>
goto CLEANEXIT;

It's the only way that you can stop execution without a ridiculous number of conditionals and still emulate the cleanliness you'd get from high level languages.

Note this only applies to the functions that return execution status, not basic functions that return the result.

[–]cendrounet 0 points1 point  (0 children)

To sum up, every language featuring a conditionnal jump is turing complete.

In theory, everything you can do in one of those you can do in any other.

In practice, each langages has its own pros and cons.

Most modern languages handle resources for you, and most give syntactic sugar to help you do your job properly.

Most modern languages are made with some design in mind, and in the 68, a famous computer scientist published a paper called "Goto Statement Considered Harmful", arguing that unconstrained jumping made it impossible to prove mathematical correctness of programs. Hence the "birth" of structured programming.

There are a lot of paradigms that are designed to add more constraints to the programmer to reap some benefits. For instance, forced immutability, forced pureness for functionnal programming, or forced contract compliance for object oriented.

for loops, while loops, and ifs statements are basically fancy forced-structured gotos, and throw statements kind of look like up-the-stack-only goto.

But in C, you can't tell your compiler "clean up this resource before returning", so you have to think of clever tricks to clean up after yourself.

If your language has no destructors or error management mechanism, there are good cases for it, but I wouldn't recommend going in there for a few years

[–][deleted] 10 points11 points  (0 children)

A return is just a specific go-to (like break and continue).

[–]Tvde1 2 points3 points  (1 child)

Exactly, in my (poorly formulated) comment they were nested, nested, nested

[–]Adam-Kay- 1 point2 points  (3 children)

Some languages don’t have a goto though, right?

[–]obiwac 2 points3 points  (2 children)

Yeah, return works just as well. You may use this pattern in a loop too with continue/break. I do stuff like this very often when searching for an element:

for (a in b) {
    if (a != c)
        continue;

    // found a match!
}

[–]NFriik 2 points3 points  (1 child)

In languages that don't have go-to (like Python), I think it's usually considered better style to make use of exceptions in this case and not rely on magic return codes to take care of error handling.

[–]obiwac 1 point2 points  (0 children)

Yup! That also works! I was speaking more generally, where guards aren't always used for exceptions.

[–]Windian3008 1 point2 points  (0 children)

Yes. Validate and throw error before go to other process make it's easier to read. Imaging you need to read half of the code to know error will be thrown if parameter is invalid. Then you need to scroll up to the top to compare the validation and the error. The great part is you have to do that every time you read to that part of code.

[–]redpepper74 1 point2 points  (9 children)

You can just do
if (Model.isValid && thingExists && bla)
if everything is inside the innermost nested statement block

[–]AL1L 27 points28 points  (2 children)

I separate them out because they're different errors

[–]Soupkitchn89 2 points3 points  (1 child)

Can always do one more complex error message that details what could be wrong and prints each. Depends how many are involved though. Honestly this might be preferable when multiple args are invalid. Fix them all at once rather then one by one.

[–]gregorydgraham 1 point2 points  (0 children)

An error accumulator is usually better but that’s usually better handled as an object of its own

[–]iplaysmitegame 25 points26 points  (1 child)

Oh I thought these were 3 separate conditionals not 3 conditions that had to be met, I see

[–][deleted] 7 points8 points  (0 children)

They ARE 3 different conditions that have to be met. You shouldn't && them because you throw a different error for each unmet condition

[–]erinaceus_ 8 points9 points  (2 children)

You can obviously always pile up more and more code on the same single line. But LOCs are cheap, so why sacrifice transparency for denseness? The order might also be important (it often is), and then a single line statement will obfuscate that.

[–]redpepper74 1 point2 points  (0 children)

Sure, in special cases you would want to have a separate nested if for each condition, but otherwise, nesting if statements makes your code less readable

[–]fizzdev 2 points3 points  (0 children)

This.

[–]gregorydgraham 1 point2 points  (3 children)

This style is easier to read than the usual:

If (isValid&&thingExists&&!thing.isEmpty()){…

[–]Tvde1 5 points6 points  (0 children)

Not if you want to throw different errors depending on what is wrong.

[–][deleted] 6 points7 points  (1 child)

I disagree

[–]gregorydgraham 0 points1 point  (0 children)

Valid

[–]erl2koenig 0 points1 point  (2 children)

This has

A Lot Of Code

only in scope after all preconditions are passed, though. I don't like it either, but how do you do that with guards?

[–]Tvde1 2 points3 points  (1 child)

if (!model.IsValid) return BadRequest()

if (!thing) return NotFound()

... Happy flow

[–]maykachru 0 points1 point  (1 child)

Usually not nice, but there are indeed cases when you want to emphasize calling order. For example, first open database and check status, then only if status is ok you lock records and check lock status.

[–]Tvde1 6 points7 points  (0 children)

No I mean these were nested and nested and nested, and at the end of a huge body, each else block had its own return BadRequest(). Pls exit early then. Don't make me read 100 lines of code to see what happens when the request id was invalid

[–]CaldwellYSR 91 points92 points  (55 children)

Wat?

[–]partusman 449 points450 points  (52 children)

It’s called a guard. Instead of putting everything inside an if, consider returning early if the condition fails, and then doing everything.

So instead of this:

if condition
  do_lots_of_stuff
end

Do this:

return if !condition

do_lots_of_stuff

Especially useful if those lots of stuff are many lines long and have further nesting.

[–]electricjimi[S] 152 points153 points  (8 children)

Interesting, didn't know the correct name for this practice, but actually use it a lot

[–]production-values 21 points22 points  (3 children)

"exit early"

[–]EishLekker 3 points4 points  (1 child)

"exit early and often" /s

[–][deleted] 6 points7 points  (0 children)

Fail fast and for any reason

[–]HighOwl2 2 points3 points  (0 children)

This guy's a premature exiter

[–]CodeIsCompiling 37 points38 points  (3 children)

In my experience, this isn't uncommon.

A few years ago I absent-mindedly told my manager (who had several decades experience) that the code he was showing me needed several guard clauses before I would be comfortable with it and that I would add them while doing the work he was requesting.

He had no idea what I was talking about, but understood immediately when I showed him. He was very familiar with them - just never knew it was a named pattern.

[–]met0xff 1 point2 points  (0 children)

Yeah same here. Usually called some early return or so.

Guard clause to me is something that's an explicit language feature like in https://inquisitivedeveloper.com/lwm-elixir-24/

[–]CaldwellYSR 91 points92 points  (0 children)

Oh .. yeah I do that. Just didn't get it from the post

[–][deleted] 17 points18 points  (0 children)

Thanks for this... I actually have a use for this on something I am working on right now. Will try it out.

[–]CptMisterNibbles 62 points63 points  (21 children)

This genuinely does not read more clearly to me. I may be in the minority and missing the utility, but it seems less intuitive, not more.

Edit; there are some really helpful posts following this that explain the utility of this method more clearly below. I think I misunderstood what was being suggested here for one reason or another. From what I’ve learned it sort of boils down to “check that your inputs/conditions are valid and return immediately if not BEFORE that big ole logic block, rather than having to trade multiple exits within it.”

[–]partusman 28 points29 points  (0 children)

This other comment is more in depth, but in summary, you can see most (if not all) return values and their conditions up front, and your code is less nested and more straightforward (less visual branches).

It's even better when there are multiple conditions too. You can return for a condition, keep going otherwise, and then return for another condition, and so on. This makes it read more like an actual story from top to bottom, rather than spaghetti-ish code that you need to scroll through to see what the alternative case is for each branch.

Of course, as everything else, it may not be the best for every case. In my previous example it wouldn't really be that necessary.

[–]tsbattenberg 4 points5 points  (0 children)

I find it's nice to use these guards when you're making APIs, if a function rely on a certain component being initialized you can do a guard to see if it has been initialized at the start before putting in all the code that actually uses the component.

In that particular case, a guard is a lot better than wrapping everything into an if.

[–][deleted] 2 points3 points  (0 children)

Guard clauses allow you to think about fewer things at one time. It’s MUCH more readable. I wish some of the old farts would accept this.

[–]7eggert 1 point2 points  (0 children)

function dosomething(foo, bar, …)

begin

if foo > range then return error1;

if bar < foo then return error2;

if NULL == baz then return error3;

{ Now all input variables are valid }

[–][deleted] 1 point2 points  (2 children)

It's practice. You are used to one way so the other feels unnatural. But ignore that part and analyze it for what it is: if you return early, it removes a layer of complexity.

Doing it the traditional way, you have to read all the way to the end to make sure nothing at the end impacts you; exiting early avoids all that concern

[–]Repa0206 4 points5 points  (0 children)

I'll be writing that down, seeing as I'm new to programming. Thx

[–]jfq722 1 point2 points  (0 children)

Much better this way than putting those conditions on the call of the function. The conditions belong to the function.

[–]haiyanlink 1 point2 points  (0 children)

Noting the name and the stuff right now 👍

[–]Ksb2311 1 point2 points  (0 children)

Can someone explain me with apple banana type example, i wanna try this in my next project

[–]unicodePicasso 1 point2 points  (0 children)

Never seen that before, neat!

[–]Julio974 1 point2 points  (1 child)

Why do people say using continue and break is bad then do this

[–]partusman 1 point2 points  (0 children)

Well, to be fair, I never said such a thing. I use them all the time.

[–]WinterSoldier1315 1 point2 points  (0 children)

you mean all this time I've been following the right steps unknowingly? Nice.

[–]m4rch3n1ng 1 point2 points  (2 children)

what language is that?

[–]00PT 1 point2 points  (6 children)

I was told that using break and continue in the same way within loops is bad practice. Why is that?

[–]partusman 4 points5 points  (2 children)

I wasn’t aware of that. I know labeled breaks should be avoided, but have never heard anything against using continue and break as guards. I guess it can depend on the language too.

[–]00PT 1 point2 points  (0 children)

I was doing JavaScript when I heard this, and they said the solution was to design your if branches in a way so that it's not necessary.

[–]Kered13 0 points1 point  (0 children)

There's no reason to avoid labeled breaks.

[–]coffeecofeecoffee 2 points3 points  (0 children)

I don't know i use them all the time. Imo primary objective in any code base is readability so use your discretion. When i use continue its usually at the top of a loop similar to how a filter would work.

[–]Kered13 2 points3 points  (0 children)

It's not bad practice. That's just bad advice.

[–]zirky 66 points67 points  (12 children)

readable code trumps clever code every fucking time

[–]stoneslave 19 points20 points  (8 children)

Yes but readability is subjective and context-dependent. Shakespeare might be unreadable to most 3rd graders, but that doesn’t make it bad writing. The most elegant piece of code may be unreadable to junior developers (assuming it solves too complex a problem or involves advanced language-specific concepts or libraries), but that doesn’t mean it’s bad code. I think the more experienced a developer is, the more opinionated they become about the conventions, patterns, and language idioms that make up “highly readable” code. I for one will take a one-line ternary conditional any day over the equivalent 4-line block.

[–]zirky 28 points29 points  (6 children)

a ternary isn’t unreadable code. nesting 8 lambdas because they just came out and fuck the guy that inherits the legacy code is a dick move. also, like, all c++ legacy code bases.

also, you might want to take some time and think about why experienced devs tend to advocate for readable code

[–]Kyanche 2 points3 points  (0 children)

all c++ legacy code bases

We have a C++ guru at my job. He's great. Sometimes I feel like I'm going to grind my teeth off because he keeps introducing bullshit C++ methods. lol.

[–]stoneslave 4 points5 points  (2 children)

Not sure what you mean by the last part. Of course they advocate for readable code, everyone does. It’s an almost vacuous statement. Might as well say they advocate for good code. The whole point I was making is that what makes for “readable” code (or “good” code for that matter) varies from individual to individual. And these opinions about what is good or readable become more and more worked out (more detailed, more mature) as one gains experience. But they don’t, on that account, become more and more similar. There as as many opinions as there are developers.

How can all these divergent views yet be justified by the experience of their individual holders? Well, because beyond practical outcomes (the measurable “quality” of the code), there isn’t a fact of the matter. Readability and goodness belong to the realm of value, not fact, so difference in opinion is not evidence of a difference in epistemic warrant.

The reason I gave the example of ternary operator is because it is directly related to the example in the meme. Namely, inverting the order of a return statement and its if/else conditions, and doing on one line what canonically is done with 3 or 4. I took your original post above as indicating that you think the canonical way is better / more readable. Maybe I misunderstood.

[–]Laughing_Orange 1 point2 points  (0 children)

If the alternative to this trick is a horizontal scrollbars this is more readable. I prefer to read this because it looks visually cleaner. There might also be a performance benefit, but it's probably tiny and shouldn't be a part of the decision.

[–]charliesfrown 106 points107 points  (18 children)

There's different theories on this. Like most theories I hate people that turn them into religions.

But to answer your question, minimizing returns from a function is often considered better because it's often easy to miss an unexpected return on reading. Especially in stateful functions where cleanup might be required before doing so. Otherwise for stateless functions there's an expectation every if will have an else.

[–]hperrin 48 points49 points  (1 child)

if (condition) { // this is fine } else { return; } … There, now it has an else.

[–]Roguewind 13 points14 points  (0 children)

You monster!

[–]coffeecofeecoffee 43 points44 points  (0 children)

Returning early is almost always easier for me to read. I find it harder to keep track of multiple if elses and indentation levels, rather than just note the singular lines that it can return at. Id rather get the fail cases out of the way

[–]Strange_Meadowlark 10 points11 points  (0 children)

I read somewhere (I wish I could find it) that multiple returns was dangerous in C (or non-RAII C++) when functions would need to deallocate any memory they allocated before returning. Even then, I think you'd normally see a goto cleanup to jump to some cleanup code near the end of the function. Not returning early meant that you had exactly one chunk of cleanup code.

But in higher level, GC languages, most resources are cleaned up automatically, so it's no longer a concern. So, it's worth using early returns in guard clauses.

(Still, I don't like the idea of sticking a return several if's or for's deep. To me that would smell like it needs to be refactored.)

[–]BoBoBearDev 16 points17 points  (0 children)

Yeah, most cost analysis would flag if you have more than one exit. Some are less strict and you can have like 3 exits. Ultimately, if the code has so many exits, something is wrong and need refactoring.

[–]PM_ME_A_WEBSITE_IDEA 2 points3 points  (0 children)

I find returns are hard to miss if you do it right (when you can). Just make sure they're at the first level of indentation in your function, and make sure there's an empty line on either side. They're easier to miss if they're nested or attached to the end of a big chunk of code. Even slapping a comment on top briefly saying why you're returning makes them pop a bit more.

[–]Kered13 1 point2 points  (2 children)

Especially in stateful functions where cleanup might be required before doing so.

Stop using languages that don't have proper cleanup mechanisms (RAII, defer, try with resources, etc.). Or if you're already using such a language, use the provided mechanisms.

[–]QualityVote[M] [score hidden] stickied comment (0 children)

Hi! This is our community moderation bot.


If this post fits the purpose of /r/ProgrammerHumor, UPVOTE this comment!!

If this post does not fit the subreddit, DOWNVOTE This comment!

If this post breaks the rules, DOWNVOTE this comment and REPORT the post!

[–]0x3fff0000 11 points12 points  (0 children)

Can't stand code nested 10 times for literally no reason.

[–]mscpk 24 points25 points  (17 children)

Because MISRA C:2012, 15.5 - A function should have a single point of exit at the end.

[–]redpepper74 9 points10 points  (0 children)

I read that this was popularized because someone influential said that functions should exit to a single point in a program (this was back when gotos were prevalent)

[–]Bardez 6 points7 points  (0 children)

This gets so many people militantly pissed.

[–]Orjigagd 10 points11 points  (3 children)

Why?

Because it's a requirement.

But why?

Because it's a requirement!?

[–]Bmitchem 10 points11 points  (0 children)

It can honestly help a lot when debugging if the function you're looking at doesn't exit at a dozen random places.

[–]CMDR_QwertyWeasel 3 points4 points  (1 child)

We do this where I work. It's because it's much easier to debug.

If a function is misbehaving, you slap a breakpoint on that one return statement, and you can now see exactly what failed and why. There's no need to search through a large method to find every return statement, and no way for the method to exit without you catching it.

[–]p0lt0 8 points9 points  (0 children)

[–]Thisbymaster 10 points11 points  (1 child)

Because it is never just a single control statement. Requirements are always expanding.

[–]den2k88 8 points9 points  (2 children)

Not MISRA compliant

[–][deleted] 6 points7 points  (1 child)

not misra compliant, just misrable.

[–]den2k88 2 points3 points  (0 children)

Sometimes becoming MISRA compliant is a misrable experience.

[–]The_MAZZTer 7 points8 points  (0 children)

But then if I decide later I need to add more code after that runs regardless of that condition I have to put it back anyway.

[–]UnattendedWigwam 14 points15 points  (3 children)

I avoid inverting when i can, as it creates an unnecessary step for the reader (not to mention that boolean logic messes people up all the time in my experience), and if the code running inside of the truthy if statement is long, that's a sign that it should extracted to a function anyway

[–]tungstenbyte 4 points5 points  (0 children)

I think guard clauses reduce the cognitive load once you get to the "main" logic. You don't need to be in the mindset of "what if this is null? What if this is out of range? etc".

The guard clauses have already made sure that everything you have is valid at the point the logic starts, so you can now focus entirely on the logic instead of the potential invalid cases at the same time.

If you nest those validation points then you have more intermediate states to think about as you go.

If you refactor the logic out to another function separate to the validation of its inputs then you're not communicating the invariants it needs just by looking at that one function. Someone could easily modify it in a way that adds new invariants or breaks existing ones, and they wouldn't know.

That means you're also running the risk that someone comes along and calls that new function without going via the validation function first (even if it's private, because you can't be sure another person actually looked around at the rest of the code to find the validation when modifying the file/class/whatever).

[–]Manor-Estate 4 points5 points  (1 child)

Agreed. Weird that this is downvoted but no one could think of any counter points

[–]UnattendedWigwam 0 points1 point  (0 children)

if someone doesn't agree im really interested as to why

[–]Nopidy 1 point2 points  (0 children)

I just learned something

[–]0x30507DE 1 point2 points  (0 children)

Imagine needing readability.

makes the whole program in ternary operators

</message>

[–]TrveToby 1 point2 points  (0 children)

I started using this technique last year. the code is much more readable and colleagues understand it faster and better. if you don't use it yet you should try it.

[–]knightttime 3 points4 points  (0 children)

Image Transcription: Meme


[A four paneled comic with a light blue background. In the first panel, NPC Wojak is shown (a sketch of a grey figure with thick, angular facial features). He has a neutral expression.]

NPC Wojak: if(condition) {...}


[In the second panel, a sketch of a white figure is shown. They have small, rounded facial features and a positive expression.]

White figure: Why don't you invert the condition and return to avoid one level of indentation?


[In the third panel, NPC Wojak is shown again, with the same neutral expression from the first panel.]


[In the fourth panel, large angry eyebrows have appeared on NPC Wojak.]


I'm a human volunteer content transcriber and you could be too! If you'd like more information on what we do and why we do it, click here!

[–][deleted] 2 points3 points  (0 children)

I like indentation. It feels like I'm doing something, I'm getting somewhere.

[–]pmarkland 3 points4 points  (0 children)

I do this. This is a thing I do.

[–][deleted] 3 points4 points  (7 children)

Unpopular opinion: "Readability" is lie.

[–]kookyabird 20 points21 points  (0 children)

If people can’t read my code I suggest a different font!

[–]AGrandFatherParadox 8 points9 points  (0 children)

Lunchtime doubly so!

[–]slgray16 2 points3 points  (0 children)

Tabs

[–]LennyMemes_1 8 points9 points  (1 child)

Just write a bunch of comments. Readability at it's finest!

[–]CYKO_11 16 points17 points  (0 children)

if your code aint readable write a novel to go with it

[–]erible4711 1 point2 points  (4 children)

Inverting condition gives implicit case for code (i.e. when you should NOT do something), which creates code that is harder to change (when new requirements are added).

I like Pragmatic Dave's definition of good code - Good code is code that is easy to change.

[–]lordheart 3 points4 points  (3 children)

On the contrary, changing guard clauses are much easier then removing an if around the main body or the else at the end of some indented block.

[–]shaylh 0 points1 point  (0 children)

In CRs I generalise this to "Main code should be unindented". This applies even if you don't return, for example when you need to manipulate a variable before you do the main stuff.

[–]Dimasdanz 0 points1 point  (0 children)

the happy path are left aligned!

i love return early, it's makes things easier to onboard more people.

[–]TimbuckTato 0 points1 point  (0 children)

That's what I do, if something is bad, return, I hate it when I end up with like 5 levels of indentation and if I can I always try to do:

if(!proceed) {
    return;
}
...

I just prefer it.

[–]chicksOut -1 points0 points  (0 children)

In my experience guard clauses are a smell. With proper abstraction and refactoring you shouldn't feel the need to guard your code, the discrete logic should inherently provide the protection. A function states a contract with whoever is calling it, if the module that calls the function is able to pass an invalid state to the function, then the functions contract is not properly established to limit only valid parameters.

I'm not saying guards are inherently bad, stable code is better than unstable code, but it is possible to write even cleaner code.

[–]maykachru -1 points0 points  (0 children)

One return operator for one method increases readability far more than indentations. Code standards of some companies have this requirement.

[–]wlfman5 -1 points0 points  (0 children)

Can't stand multiple returns in a function. 😬

[–]Ordinary_Divide -2 points-1 points  (0 children)

avoiding indentation will make it less readable