• (cs)

    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.

  • (cs)

    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?

  • (cs)

    Multiple returns are bad because people do this:

    void Function()
    {
       MyClassThatRequiresCleanup c = Initialize();
       if(someCondition) return;
       c.Cleanup();
    }
    

    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.

  • dkallen (unregistered) in reply to AssBlaster

    They are also used by people who DO know what an exception is, and prefer unbloated code.

    Or... was that a troll?

  • Sh (unregistered) in reply to AssBlaster
    AssBlaster:
    Multiple return points are bad for the same reasons GOTO's are mostly bad. Also, they tend to be used a lot by people who don't know what an exception is.

    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.

  • PRMan (unregistered) in reply to AssBlaster
    AssBlaster:
    Multiple return points are bad for the same reasons GOTO's are mostly bad. Also, they tend to be used a lot by people who don't know what an exception is.

    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.

  • Dave (unregistered)

    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.

  • PRMan (unregistered) in reply to Sutherlands
    Sutherlands:
    Multiple returns are bad because people do this:
    void Function()
    {
       MyClassThatRequiresCleanup c = Initialize();
       if(someCondition) return;
       c.Cleanup();
    }
    
    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.

    FYI, they adding "using" to VB, if anyone cares...

    http://msdn.microsoft.com/en-us/library/htd05whh%28v=vs.80%29.aspx

  • valetudo (unregistered) in reply to boog
    boog:
    hoodaticus:
    Mutliple returns are only bad when used by a psychotic code monkey in his ten page long methods with flow control lines jumping around all over like Nightcrawler after he shot the president in X-Men 2. The reason is because it's nigh-impossible to tell which path their shitty code took on its way to ruining your day.
    If there are multiple returns, you're looking for the returns. If there's only one return, you're looking for where the return variable was set. I would wager the two tasks are equally difficult, so I'm still not convinced that early returns are necessarily a bad thing.
    hoodaticus:
    Developers blessed with The Gift should completely ignore that rule, since it tends to make crystal-clear, well-factored code even clearer, and you'll probably never need to mentally reverse-execute their code anyway.
    Or maybe another way to put it: bad design is bad design. If you have a massive, mostly-messy method that also happens to use early returns, it is not a good example of why early returns are bad. The code just sucks. A good example would show how bad code was improved by only removing early returns. I have yet to see such an example myself.
    Spot on Boogie.... Any argument about creating arbitrary rules ignores the fact that every situation is different.

    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.

  • ratis (unregistered) in reply to Sutherlands
    Sutherlands:
    Multiple returns are bad because people do this:
    void Function()
    {
       MyClassThatRequiresCleanup c = Initialize();
       if(someCondition) return;
       c.Cleanup();
    }
    
    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.
    Don't most (modernish (c++,c#,java) - and that code looks reasonably modern) compilers warn/error about an unreachable branch?

    I have a suspicion even my C compiler warns on that....

  • (cs) in reply to Dwedit
    Dwedit:
    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.
    True, but there are two extra .locals init parameters and four extra instructions in the IL to populate the extra variables at the beginning of the method, and then there's this:
    if (checkCase)
         lStr = str;
    else
         lStr = str.ToUpper();
    

    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.

  • reductio ad ridiculum (unregistered) in reply to ratis
    ratis:
    Sutherlands:
    Multiple returns are bad because people do this:
    void Function()
    {
       MyClassThatRequiresCleanup c = Initialize();
       if(someCondition) return;
       c.Cleanup();
    }
    
    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.
    Don't most (modernish (c++,c#,java) - and that code looks reasonably modern) compilers warn/error about an unreachable branch?

    I have a suspicion even my C compiler warns on that....

    It may be a reachable branch. Whether or not its path is executed depends on the definition of "someCondition". If it's a hardcode variable, I believe a compiler can catch it, otherwise it may be a runtime condition.

    rar

  • reductio ad ridiculum (unregistered) in reply to hoodaticus
    hoodaticus:
    boog:
    AssBlaster Returns:
    I'm not saying multiple returns are ALWAYS bad, especially in an embedded system without {insert several unreasonable constraints here}.
    That's all well and good, but when are they bad? I'm not yet convinced they ever are.
    AssBlaster Returns:
    As to the guy who asked why are GOTOs bad...
    I must have missed the comment where the guy asked why GOTOs are bad.
    Mutliple returns are only bad when used by a psychotic code monkey in his ten page long methods with flow control lines jumping around all over like Nightcrawler after he shot the president in X-Men 2. The reason is because it's nigh-impossible to tell which path their shitty code took on its way to ruining your day.

    Developers blessed with The Gift should completely ignore that rule, since it tends to make crystal-clear, well-factored code even clearer, and you'll probably never need to mentally reverse-execute their code anyway.

    Yep, good answer.

    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

  • trtrwtf (unregistered) in reply to AssBlaster
    AssBlaster:
    Multiple return points are bad for the same reasons GOTO's are mostly bad.

    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...

  • trtrwtf (unregistered) in reply to no u
    no u:
    An Old Hacker:
    The really sad part about that is, afaik, in C, there really is only one return point. A return inside the method is implemented as a goto the real return...

    and in what way is that at all sad?

    The problem with goto's is that developers get confused - not because there is anything actually wrong with the construct

    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)

  • trtrwtf (unregistered) in reply to trtrwtf
    trtrwtf:
    An Old Hacker:
    The problem with goto's is that developers get confused - not because there is anything actually wrong with the construct
    There is something very wrong with the construct: it has no semantics.

    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.

  • trtrwtf (unregistered) in reply to Anonymous
    Anonymous:
    The coding style espoused by TPD mandated all methods be commented, and those comments indicate which methods called the current method.

    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)

  • trtrwtf (unregistered) in reply to boog
    boog:
    hoodaticus:
    The reason is because it's nigh-impossible to tell which path their shitty code took on its way to ruining your day.
    If there are multiple returns, you're looking for the returns. If there's only one return, you're looking for where the return variable was set. I would wager the two tasks are equally difficult, so I'm still not convinced that early returns are necessarily a bad thing.

    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.

  • (cs)

    Personally, early returns have their place, like below:

    public bool DoStuff(int someId) {
    if (!IsValid(someId))
    return false;
    // Do complex processing
    }
    VS.
    public bool DoStuff(int someId) {
    var retVal = false;
    if (IsValid(someId)) {
    // Do complex processing
    retVal = true;
    }
    else
    retVal = false;
    return retVal;
    }
    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...

    return false;
    Are you really going to "process" this resume for even one second longer than you should? Fuck no. paper shredder sound

  • (cs) in reply to Sutherlands
    Sutherlands:
    Multiple returns are bad because people do this:
    void Function()
    {
       MyClassThatRequiresCleanup c = Initialize();
       if(someCondition) return;
       c.Cleanup();
    }
    
    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.

    Explain what's wrong with that then.

  • trtrwtf (unregistered) in reply to C-Octothorpe
    C-Octothorpe:
    Personally, early returns have their place

    Aside from the grammar, I agree with this entirely.

  • (cs) in reply to trtrwtf
    trtrwtf:
    C-Octothorpe:
    Personally, early returns have their place

    Aside from the grammar, I agree with this entirely.

    It's 3:45 am... You expect good grammar? :)

  • trtrwtf (unregistered) in reply to C-Octothorpe
    C-Octothorpe:
    trtrwtf:
    C-Octothorpe:
    Personally, early returns have their place

    Aside from the grammar, I agree with this entirely.

    It's 3:45 am... You expect good grammar? :)

    Yep.

  • (cs) in reply to Hortical
    Hortical:
    Matt Westwood:
    Oh and it occurs to me why they call it "reinventing the wheel".

    It's because the code so described tends to be in a loop, and it goes round and round and round and round and round and ...

    Or maybe the phrase was specifically chosen to compare the re-inventor to a caveman - not so much the thing reinvented to the wheel.

    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.

  • fulton (unregistered) in reply to AssBlaster
    AssBlaster:
    ... Also, they tend to be used a lot by people who don't know what an exception is.

    Unfortunately, a lot of people also confuse exceptions with return codes.

  • (cs)

    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:

    // Extension method for missing string.Replace() signature including StringComparison enum
    public static class StringExtensions
    {
        public static string Replace(this string originalString, string oldValue, string newValue, StringComparison comparisonType)
        {
            int startIndex = 0;
            while (true)
            {
                startIndex = originalString.IndexOf(oldValue, startIndex, comparisonType);
                if (startIndex == -1)
                    break;
    
                originalString = originalString.Substring(0, startIndex) + newValue + originalString.Substring(startIndex + oldValue.Length);
    
                startIndex += newValue.Length;
            }
    
            return originalString;
        }
    }
  • QJo (unregistered) in reply to AssBlaster Returns
    AssBlaster Returns:
    I'm not saying multiple returns are ALWAYS bad, especially in an embedded system without {insert several unreasonable constraints here}.

    BTW, I don't like this:

    if (catastrophic_failure_that_should_be_logged) return;
    
    //probably someone trying to hack the system. fuck it.
    if (!ValidID(user_id)) return;
    
    

    I also don't like this:

    if (PassCondition1())
    {
       if (PassCondition2())
       {
         if (PassCondition3())
         {
            MagicHappens();
         } else
         {
            //this should not happen. but i guess it did LOL
         }
       } else
       {
          //faiL! LoL
       }   
    } else
    {
       //failed condition 1 lolz
    }
    

    Inserting a new condition beween 1 and 2 means, at best, re-indenting all that code and at worst getting completely lost.

    As to the guy who asked why are GOTOs bad, well, they are bad because 99% of us aren't trying to write an operating system kernel or paying attention to how much the code is screwing with the CPU's cache in order to shave a few cycles off our 3D game engine.

    Just my 2 cents.

    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.

  • fulton (unregistered) in reply to Sutherlands
    Sutherlands:
    Multiple returns are bad because people do this:
    void Function()
    {
       MyClassThatRequiresCleanup c = Initialize();
       if(someCondition) return;
       c.Cleanup();
    }
    
    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.

    ... 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.

  • Jibble (unregistered) in reply to Frank
    Frank:
    Your point is well taken if you are implementing exceptions. But even in a language which supports exceptions natively, exception handling can result in much slower code.

    On every compiler I've used in the last ten years no extra code is executed unless an exception is actually thrown.

    Frank:
    Thus, it is often not used in embedded code. In that case, I think multiple return points can actually result in much faster and more maintainable code.

    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).

  • Jake (unregistered) in reply to AssBlaster

    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"...

  • Jibble (unregistered) in reply to fulton
    fulton:
    I would always favour early returns, mainly because it makes the code more readable

    Strongly disagree.

    fulton:
    *plus* it more or less forces you to be exception safe.

    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.

  • QJo (unregistered) in reply to Jibble
    Jibble:
    fulton:
    I would always favour early returns, mainly because it makes the code more readable

    Strongly disagree.

    fulton:
    *plus* it more or less forces you to be exception safe.

    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.

    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.

  • codemonkey73 (unregistered) in reply to C-Octothorpe

    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.

    public bool DoStuff(int someId) {
      var valid = IsValid(someId);
      if (valid) {
        // Do complex processing
      }
      return valid;
    }
    
  • Someone who can't be bothered to login from work (unregistered) in reply to Dwedit
    Dwedit:
    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.

    Aye, immutable strings are fun.

  • (cs)

    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 :)

  • AndyC (unregistered)

    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.

  • Tim Rowe (unregistered) in reply to An Old Hacker
    An Old Hacker:
    The really sad part about that is, afaik, in C, there really is only one return point. A return inside the method is implemented as a goto the real return...
    That will be true of any programming language when you get down to the machine code level (possibly depending on the platform). It doesn't matter. The purpose of higher level languages is to abstract those things away, which C does.

    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).

  • trtrwtf (unregistered) in reply to Jibble
    Jibble:
    fulton:
    I would always favour early returns, mainly because it makes the code more readable

    Am incorrect

    FTFY

  • trtrwtf (unregistered) in reply to topcat_arg
    topcat_arg:
    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?)

    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.

  • Hortical (unregistered) in reply to Matt Westwood
    Matt Westwood:
    Hortical:
    Matt Westwood:
    Oh and it occurs to me why they call it "reinventing the wheel". It's because the code so described tends to be in a loop, and it goes round and round and round and round and round and ...
    Or maybe the phrase was specifically chosen to compare the re-inventor to a caveman - not so much the thing reinvented to the wheel.
    Yeah yeah yeah but that's just too bleeding obvious to even mention. Doesn't anyone have a fucking sense of humour on this fucking website any more?
    Hmmm.. If it's too bleeding obvious to even mention, isn't it too bleeding obvious to mention how bleeding obvious it is?
  • Hortical (unregistered) in reply to Matt Westwood
    Matt Westwood:
    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.

    "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.

  • QJo (unregistered) in reply to Hortical
    Hortical:
    Matt Westwood:
    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.

    "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.

    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.

  • radarbob (unregistered)

    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).

  • Luiz Felipe (unregistered)

    Im amazed that no one said about COMEFROM.

  • Hortical (unregistered) in reply to QJo
    QJo:
    Hortical:
    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.

    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.
    You can't just hold it? What are you, an old woman?

    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.

  • (cs) in reply to trtrwtf
    trtrwtf:
    boog:
    hoodaticus:
    The reason is because it's nigh-impossible to tell which path their shitty code took on its way to ruining your day.
    If there are multiple returns, you're looking for the returns. If there's only one return, you're looking for where the return variable was set. I would wager the two tasks are equally difficult, so I'm still not convinced that early returns are necessarily a bad thing.

    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.

    This.

  • (cs) in reply to C-Octothorpe
    C-Octothorpe:
    trtrwtf:
    C-Octothorpe:
    Personally, early returns have their place

    Aside from the grammar, I agree with this entirely.

    It's 3:45 am... You expect good grammar? :)
    That was more syntax than grammar, but then, that makes two of you.

  • (cs) in reply to Luiz Felipe
    Luiz Felipe:
    Im amazed that no one said about [post-jump construct that shall not be named].
    FTFY.
  • Fat (unregistered)

    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?

  • (cs) in reply to codemonkey73
    codemonkey73:
    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.
    public bool DoStuff(int someId) {
      var valid = IsValid(someId);
      if (valid) {
        // Do complex processing
      }
      return valid;
    }
    
    First, I'd like to point out that you're being a real pedantic dickweed if you expect code that I quickly wrote in a forum at 3:00AM would compile.

    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.

Leave a comment on “The Phantom Duo's ChangeWord”

Log In or post as a guest

Replying to comment #:

« Return to Article