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

Studies have looked at MISRA, I'm not aware of any for the JSF guidelines. For MISRA there's a mix, some of the rules seem to be effective (fewer defects in compliant software), some are the opposite (code which obeys these rules is more likely to have defects) and some were irrelevant.

Notably this document is from 2005. So that's after C++ was standardized but before their second bite of that particular cherry and twenty years before its author, Bjarne Stroustrup suddenly decides after years of insisting that C++ dialects are a terrible idea and will never be endorsed by the language committee, that in fact dialects (now named "profiles") are the magic ingredient to fix the festering problems with the language.

While Laurie's video is fun, I too am sceptical about the value of style guides, which is what these are. "TABS shall be avoided" or "Letters in function names shall be lowercase" isn't because somebody's aeroplane fell out of the sky - it's due to using a style Bjarne doesn't like.





The "good" rules are like "don't write off the end of an array", and the bad ones are like "no early returns" or "variable names must not be longer than 6 characters". 95% of the "good" rules are basically just longer ways of saying "don't invoke undefined behavior".

Why is "no early returns" not a good rule?

I do early returns in code I write, but ONLY because everybody seems to do it. I prefer stuff to be in predictable places: variables at the top, return at the end. Simpler? Delphi/Pascal style.


Early returns makes the code more linear, reduces conditional/indent depth, and in some cases makes the code faster. In short, it often makes code simpler. The “no early returns” is a soft version of “no gotos”. There are cases where it is not possible to produce good code while following those heuristics. A software engineer should strive to produce the best possible code, not rigidly follow heuristics even when they don’t make sense.

There is an element of taste. Don’t create random early returns if it doesn’t improve the code. But there are many, many cases where it makes the code much more readable and maintainable.


I remember having this argument with my professor at the school, who insisted that a function should have only one "return" clause at the very end. Even as I tried, I could not get him to explain why this would be valuable and how does this produce better code, so I'm interested on hearing your take on this?

It helps prevent bugs with state. The apple login bypass bug comes to mind.

Basically, you have code in an "if" statement, and if you return early in that if statement, you might have code that you needed to run, but didnt.

Forcing devs to only "return once" encourages the dev to think through any stateful code that may be left in an intermediate state.

In practice, at my shop, we permit early returns for trivial things at the top of a function, otherwise only one return at the bottom. That seems to be the best of both worlds for this particular rule.


The rule of thumb I use is to only have one return after modifying state that will persist outside the function call.

Thank you!

> The apple login bypass bug comes to mind.

I think you're talking about this "goto fail" bug?

https://teamscale.com/blog/en/news/blog/gotofail

> In practice, at my shop, we permit early returns for trivial things

Are you also writing C or similar? If so, then this rule is relevant.

In modern languages, there are language constructs to aid the cleanup on exit, such as using(resource) {} or try {} finally {} It really does depend on if these conveniences are available or not.

For the rest of us, the opposite of "no early return" is to choose early return only sometime - in cases where results in better code, e.g. shorter, less indented and unlikely to cause issues due to failure to cleanup on exit. And avoid it where it might be problematic. In other words, to taste.

> Kent Beck, Martin Fowler, and co-authors have argued in their refactoring books that nested conditionals may be harder to understand than a certain type of flatter structure using multiple exits predicated by guard clauses. Their 2009 book flatly states that "one exit point is really not a useful rule. Clarity is the key principle: If the method is clearer with one exit point, use one exit point; otherwise don’t".

https://en.wikipedia.org/wiki/Structured_programming#Early_e...

this thinking is quite different to say, 25 years earlier than that, and IMHO the programming language constructs available play a big role.


For me it's mostly about indentation / scope depth. So I prefer to have some early exits with precondition checks at the beginning, these are things I don't have to worry about afterwards and I can start with the rest at indentation level "0". The "real" result is at the end.

Because good code checks pre conditions and returns early if they are not met.

> Why is "no early returns" not a good rule?

It might be a good guideline.

Its not a good rule because slavishly following results in harder to follow code written to adhere to it.


The "no early returns" rule came about because was a good rule in context, specifically C and FORTRAN code before roughly 1990. It was part of "structured programming", contemporary to "Go To Statement Considered Harmful", Dijkstra, 1968. And it became received wisdom - i.e. a rule that people follow without close examination.

For example of the rule, a function might allocate, do something and then de-allocate again at the end of the block. A second exit point makes it easy to miss that de-allocation, and so introduce memory leaks that only happen sometimes. The code is harder to reason about and the bugs harder to find.

source:

> A problem with early exit is that cleanup statements might not be executed. ... Cleanup must be done at each return site, which is brittle and can easily result in bugs.

https://en.wikipedia.org/wiki/Structured_programming#Early_r...

About 90% of us will now be thinking "but that issue doesn't apply to me at all in $ModernLang. We have GC, using (x) {} blocks, try-finally, or we have deterministic finalisation, etc."

And they're correct. In most modern languages it's fine. The "no early returns" rule does not apply to Java, TypeScript, C#, Rust, Python, etc. Because these languages specifically made early return habitable.

The meta-rule is that some rules persist past the point when they were useful. Understand what a rule is for and then you can say when it applies at all. Rules without reasons make this harder. Some rules have lasted: we typically don't use goto at all any more, just structured wrappers of it such as if-else and foreach


> And they're correct. In most modern languages it's fine. The "no early returns" rule does not apply to Java, TypeScript, C#, Rust, Python, etc. Because these languages specifically made early return habitable.

Early return is perfectly manageable in C as long as you aren't paranoid about function inlining. You just have a wrapper that does unconditional setup, passes the acquired resources to a worker, and unconditionally cleans up. Then the worker can return whenever it likes, and you don't need any gotos either.


> In C, you just have a wrapper that does unconditional setup, passes the acquired resources to a worker, and unconditionally cleans up. Then the worker can return whenever it like

Right, so you allow early return only in functions that do not have any setup and clean-up - where it's safe. Something like "pure" functions. And you describe a way to extract such functions from others.


> variable names must not be longer than 6 characters

My memory might be lapsing here, but I don't think MISRA has such a rule. C89/C90 states that _external_ identifiers only matter up to their first 6 characters [1], while MISRA specifies uniqueness up to the first 31 characters [2].

[1] https://stackoverflow.com/questions/38035628/c-why-did-ansi-...

[2] https://stackoverflow.com/questions/19905944/why-must-the-fi...


Bjarne's just a guy, he doesn't control how the C++ committee vote and doesn't remotely control how you or I make decisions about style.

And boiling down these guidelines to style guides is just incorrect. I've never had a 'nit: cyclomatic complexity, and uses dynamic allocation'.


If one limited C++ profiles to have no semantic effect and to not change code generation, only subsetting, they would be way simpler than dialects, right? More limited, yes, but also way simpler.

It would enable preventing a lot of footguns, at the very least, like vector<bool>.

Wait, you're one of those Rust evangelists, right? Have you been paid like fasterthanlime?


We've banned this account for continual guidelines breaches across multiple accounts.

You do realize that there's a handful of literally the same people here on HN continuously evangelizing one technology by constantly dissing on the other? Because of the pervasiveness of such accounts/comments it invites other people, myself included, to counter-argue because most of the time the reality they're trying to portray is misrepresented or many times simply wrong. This is harmful and obviously invites for a flame war so how is that not by the same principle you applied to above account a guideline breach too?

We act on what we see, and we see what people make us aware of via flags and emails.

Comments like yours are difficult because they’re not actionable or able to be responded to in a way you’ll find satisfying if you don’t link to the comments that you mean.

Programming language flamewars have always been lame on HN and we have no problem taking action against perpetrators when we’re alerted to them.


"No semantic effect" is one of those recurring C++ tropes like the "subset of a superset" or "trading performance for safety" that I think even its defenders ought to call bullshit on. The insistence on "No semantic effect" for attributes has poisoned them badly, and the choice to just ignore the semantic implications for Bjarne's C++ 20 Concepts makes this a poor substitute for the concepts feature as once imagined at the start of the century.

I doubt I can satisfy you as to whether I'm somehow a paid evangelist, I remember I got a free meal once for contributing to the OSM project, and I bet if I dig further I can find some other occasion that, if you spin it hard enough can be justified as "payment" for my opinion that Rust is a good language. There was a nice lady giving our free cookies at the anti-racist counter-protests the other week, maybe she once met a guy who worked for an outfit which was contracted to print a Rust book? I sense you may own a corkboard and a lot of red string.


But what’s the relevance of all of this to bird law?



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

Search: