- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
Technically, the line about "// create copies of some of the parameters; you can never have too many copies" is flat out wrong, there are never any copies created of the input string, since they are just references to the original strings themselves.
But a bunch of copies of strings are are created during the part where it calls str.Remove and str.Insert in a loop.
Admin
Wait, was this method being called by the game show MatchWord? Why the fuck would Nipsy Russell or Charles Nelson Reiley need to call a string replace function?
Admin
Multiple returns are bad because people do this:
Of course, you can get around that by using try/finally (most languages), using (C#), or by not being a bad programmer, but the "rules" were created when most of these things were not around.
Admin
They are also used by people who DO know what an exception is, and prefer unbloated code.
Or... was that a troll?
Admin
Sigh, gotos are (mostly) bad because the give multiple points of ENTRY to a piece of code, not because they give multiple points of EXIT.
And, I know what an exception is, but multiple returns make for a nice, easy, clean, functional style sometimes. It's a matter of chosing the right tool.
Admin
Since Borland and Microsoft's codebases use early return extensively as do many experts, what makes you think this?
There is absolutely no confusion when hitting a return. You are exiting the method. When going to a GOTO, you can go up, down, sideways, etc.
Admin
Just wanted to say as a non-coder/hobbyist who likes the DWTF, i appreciated the sarcastic comments in this entry. I muck around with code but I know my (severe) limits and I follow the DWTF as a way of learning. I can usually work out more or less what's wrong with CodeSODs but a lot of it goes over my head. If more entries had this type of comment I'd find it even more useful and entertaining. Cheers and thanks for all the good work.
Admin
FYI, they adding "using" to VB, if anyone cares...
http://msdn.microsoft.com/en-us/library/htd05whh%28v=vs.80%29.aspx
Admin
an unrelated example: A lengthy Change process might make sense for large deployments where it is critical to get things right (depending on what is making it long, of course), but the same process may not adapt well to emergency fixes that are needed to keep an application processing - yet most places I've worked have the same process for any change (although some allow the retrospective paperwokr for emergnecy change).
How does this relate? Not well, but the point is it is stupid to make arbitrary rules, and even stupider to follow them as anything more than guidelines - and as with any guideline, you assess what the purpose of it is, rather than what it says when considering whether it should be applied or not. Sometimes, there may be a standard set for a reason (It doesn't have to be an overly solid reason - "That's how we do it" might be a reasonable reason where we are adding to a large application where we want some consistency between various components). More often, though, it seems there is a standard set "because I read on the internet that case statements are more efficient than ifs", or "because Java defaults that to null anyway", or "because any programmer worth their salt understands that's a pointer" or something else...
IT is a very broad field, and within that field Software Engineering (even if we reduce it to just programming) is a massive area in itself. It simply does not make sense to expect that a single rule will apply in all circumstances - and even on a site like this (where perhaps most of us are more guilty of WTFs than we like to admit) it is clear that opinion is divided over even simple things like goto, return, magic numbers, macros etc. Assuming some of us actually work in the real world (I do, and I suspect many others here do too), then (given our divided opinion) there must be all sorts of variation in the software we produce. I'm pretty happy with the stuff I do, and I'm sure even those whose views differ to mine on some of these issues would be pretty happy with their code too...
Summary: Whatever works for you works for you. There is not always a right and wrong.
Admin
I have a suspicion even my C compiler warns on that....
Admin
Which runs every time there's a replace and wastes two extra IL instructions each time, whichever path it takes.
It also makes the code less clear. It's kind of a winning practice, really - achieving mediocrity in both performance and elegance in parallel.
Addendum (2011-08-10 22:08): Make that one wasted instruction per replace, not two. I was counting ldarg_1 when I shouldn't have.
Admin
rar
Admin
Ok class, here's an example. Many of us may remember learning in grade school that starting a sentence with a conjunction is "bad", and not to do it. We learned it then, and many of us still remember "the rule".
But think of the target audience--beginners in grammar. Say an excited little boy is telling a story. And he wants to tell you about it. And he thinks it's really great. And he's writing it down. And it's just like when he talks. And so he adds the ands, and the buts. And...you get the idea.
Now take a look at a good novelist. It's usually not too hard to find places where they used "And" or "But" at the beginning of the sentence. It makes sense, and it's fine.
Using a conjunction at the start of a sentence can be good grammer. Using it appropriately requires more than a beginners skill. It's correct to tell beginners that the rule is "don't start w/ conjunctions". Intermediate writers can get away with it, but need to keep it in mind. Advanced writers use it appropriately to great effect.
Substituting "goto" or "return" for "conjunction" in the little story above is left as an exercise for the reader. Extra credit for turning it into a car analogy.
rar
Admin
Do you say this because you don't understand the difference between a goto and a return, or because you've been told that a return is "just like a goto" or because you've been told that multiple exits are bad and that gotos are bad and you just threw them together in your mind, or why are you saying this? I'd really like to understand what confusion on your part led to this...
Admin
There is something very wrong with the construct: it has no semantics. A return, an if/else, a while, a for - all of these have limitations on their use which give them an inherent semantics. goto communicates nothing to the programmer, ergo it is a bad construct. If it's all the language offers for flow control, and you must use the language, then you use it, but a higher-level language should never allow free-form jumps (and no higher-level language that I know of does, aside from old-school basic)
Admin
That is to say: the construct confuses developers - it's not just that they get randomly confused for no reason, it's that when you throw in arbitrary jumps into arbitrary points in the code, confusing things happen, and the point of language design is to minimize that confusion.
Admin
There's a nice big wthffftlop right there. A method shouldn't need to know who calls it: it should define what it's going to do, and what it needs to do it, and it should do that, and return a well-defined "screw you" if you give it bad data to work with. The only reason to want that comment is so you can rewrite the function to suit the needs of the calling code: that's wrong, just write the function you need, and if you want to you can refactor them together later.
(not to mention that the comment listing calling functions is out of date by the time the next guy checks it out of source control and he's got to go through and verify the information anyway, so wtf once again)
Admin
Simple answer: the problem hoodaticus is highlighting is methods spanning lots of pages, not multiple points of return.
Decompose long methods into short single-purpose ones and the early-return problem isn't a problem.
Admin
Personally, early returns have their place, like below:
VS. Which one is more clear?Personally, I think the first example because by scanning the first few lines you already know one thing you don't have to think about while reading the code any further: the ID is valid. The less things you need "in memory" while reading code, the faster it tends to go.
Also, unless you create bracket hell, more code will be executed even though you know it's not in a valid state to continue anyway, and it makes it harder to debug because execution does go through the entire method body.
Think about it this way: you're looking through a huge pile of resumes, and have several criteria it must match in order to save it from the shredder. You pick up a resume that starts out with several spelling errors (hmmm, they live in Sincenatie?) and listing their current experience as couch potato...
Are you really going to "process" this resume for even one second longer than you should? Fuck no. paper shredder soundAdmin
Explain what's wrong with that then.
Admin
Aside from the grammar, I agree with this entirely.
Admin
Admin
Yep.
Admin
I believe the wheel was invented significantly later than the era when humankind was living in caves. It is also worth pointing out that early man was considerably more resourceful, creative and inventive than your average C21 office-dweller, some of whom haven't even learned how to ensure that the utensils for the manufacture of heated caffeinated beverages are clean and dry before they are inserted into the receptacle in which the raw materials for such beverages are stored.
Yes, you, I'm looking at you, go and wash your spoon immediately and never put a wet dirty spoon into either the coffee or the sugar again, or you're on yet another disciplinary.
Admin
Unfortunately, a lot of people also confuse exceptions with return codes.
Admin
The real WTF is why .NET Framework after 10 years still doesn’t include a String Replace function signature that takes a StringComparison enum.
So here’s one I used yesterday:
Admin
I might implement the above something like:
[code] validConditions = true;
if (!PassCondition1()) validConditions = false;
if (validConditions && !PassCondition2()) validConditions = false;
if (validConditions && !PassCondition3()) validConditions = false;
if (validConditions) { // Magic happens } return; {/code]
It depends on the nature of the programming problem being solved.
I might be tempted to reverse the condition of the tests and call them FailCondition1 - 3 so as to make the flow clearer.
Admin
... or you put the cleanup code into the destructor, following RAII and make it exception safe as well (without littering the code with unnecessary try/catch blocks).
I would always favour early returns, mainly because it makes the code more readable plus it more or less forces you to be exception safe.
Admin
On every compiler I've used in the last ten years no extra code is executed unless an exception is actually thrown.
I'll let you use multiple return points if, and ONLY IF, it's in a function which returns boolean true/false for success/error.
Even so, you really ought to be using a proper programming language - this isn't the 1970s any more. Exceptions do much more than act like a fancy return statement (stack unwinding, RAII-cleanup, etc).
Admin
GOTO's are mostly bad because of structure (not because of syntax). Read E. Dijkstra's paper "GOTO considered harmful" to verify this for yourself, if you wish. While you're at it, make sure to also assess Don Knuth's response to it.
Neither multiple return points nor exceptions cause any structural problems in software. However, due to the need of temporary variables, single returns will typically be more memory-intensive and slower than their early-return counterparts. Also, single-return code makes it tempting to just slap any new code at the end of a function, rather than at the position where it would be most efficient and most readable. THAT causes problem with the structure of code. And don't even get me started on "else" hundreds of lines after the original "if"...
Admin
Strongly disagree.
No coding convention will "force" anybody to do anything (try reading a few articles here...)
Much better to learn to use RAII for everything. It's difficult to forget to clean up when the compiler is writing that bit of the code for you.
Admin
I strongly disagree that it's appropriate to strongly disagree about any software design principle. There are situations where a good design may well incorporate some of the paradigms which are in question - and on the other hand there are situations where it is definitely not correct to use a particular design pattern.
The good engineer uses whichever pattern is best. The less good engineer uses the general rules of thumb and questions them where it feels wrong to apply those rules. The engineers who blindly use the rules without question is inferior to both. The worst engineers, of course, are those who never bothered to learn the rules and has no feel for what makes a quality piece of work.
Admin
If you are going to use a single return point example write it properly rather than as ugly as possible. Oh, and you fail to return in your multiple return example so that code doesn't even build.
Admin
Aye, immutable strings are fun.
Admin
All this goto rampage.. I always have a feeling.. that we don't use it because it look bad. When I remember basic or assembler, I recall using it all the time.. and thinking out loud, what´s the diference with all this call to functions (gosub, return?) or this call to events (goto?) or even any branch without condition in assembler?
I think that the problem, is really stetic :)
Admin
The advantage of a single return should be obvious when, as part of codebase maintainence, you're required to add another post condition to a function (maybe something has to be logged or whatever). Structuring methods with a single exit point shows code written with maintainence in mind.
Which is not to say that some cases - particularly the immeadiate drop out for invalid parameters - are never appropriate, but it's the sign of good code when multiple returns are used sparingly.
Admin
As far as I am concerned, single exit point doesn't matter as long as it's clear and it's HK reducible. (Yes, I know that the 'K' implies a single exit point, but that's after all reducible nodes have been reduced).
Admin
FTFY
Admin
It's not so much "what's the the difference?" as "what's the similarity?" And the only similarity is that both involve a jump instruction in the object code. Beyond that they have nothing at all in common.
Admin
Admin
"People" are little more than trained monkeys with car keys.
I'll have you know that I never touch the coffee maker.
...or use the office restroom.
...or sit in anyone's chair but mine. Sometimes they smell like farts.
...or get close enough to smell them.
...or let them see me eat.
Admin
An admirable lifestyle, I expect, but to live by the second of the above would cause a certain amount of personal discomfort. Unless, of course, one had a sufficient quantity of empty bottles available under one's desk.
Admin
GOTO, multiple uses or otherwise, is like Jessica Rabbit who famously said "I'm not bad, I'm just drawn that way."
GOTO is code smell that (likely) means the coder does not know how to write structured code. In the good 'ole days (ha!) there was some plausable deniability in that (early versions of) cobol did not have "scope limiters" - like "end-if" , "end-switch", or braces. Hard to imagine unless you've been there, but true. GOTO was king, and abused mercilessly.
Therefore it was possible, and common, to have a large nested conditional structures - if inside switch inside while inside ... All terminated (i.e. scoped) with a single period at the end. The one that gave me nightmares was a single "method" a page long 8 Ifs deep with about 10-12 GOTOs sprinkled throughout. The entire structure was terminated at the same point - at the very end. You literally could not change any part of that code without breaking all of it.
I guess the sad point is Give a programmer a Class and he'll be the present-day Biff to future Marty code maintainers; Teach a programmer how to use a Class and the future is at least hopeful (a little Back to the Future referencing there).
Admin
Im amazed that no one said about COMEFROM.
Admin
I remember one day I was leaving home and thought: "Oh, I need to pee", but I was already rolling down the street.
11.5 hours later I get home and remember "Oh, I need to pee". (True story, bro)
No problem. Except I had to flush halfway through to keep the bowl from overflowing. And the splashback was something awful.
Admin
Admin
Admin
Admin
Hm.
I really don't understand what's the big WTF? Can someone explain this to me?
Sure, there are some additional copies of input parameters, and single return point (which is arguably not a defect), but I think it's not that bad. The code is pretty clear, despite the unfortuante parameters naming. The only bad thing I can see is unnecessary lStr = str every time the replacement is made. In the other hand, the alternative is watching over the difference in lStr and str lengths, which can lead to more complicated code. The guys even managed to escape the infinite loop problem when replacing "a" with "aa", which might be quite elusive.
On the other hand, if the standard library has case-insensitive Replace, my point is obviously invalid. Is this what the WTF is?
Admin
Anyway, can explain to me why it's necessary to create and assign a local variable and carry its value throughout the method body? If you returned false on !IsValid(), you'd lose two lines of code and a variable (that you no longer have to keep track of while debugging) without losing any readability.
This also has the nice side-effect of implying that it is in a valid state if it passes that first (or ten) check(s).
From personal experience whenever you see a single return, the method is usually much more complex than either of our examples. Check out this perfect example of what a badly implemented single return looks like. Why check it four fucking times when you know immediately that you're not going to do any more processing anyway? Just so you have a single return? This makes it that much harder to read and debug for the next developer who has to maintain your code...
At the end of the day, whatever yields the cleanest, most maintainable and performant (I hate using that word) code should be used. I use both methods, but I will usually lean more towards the early return as it tends to produce code that is more clear, IMHO.