Want to read Slashdot from your mobile device? Point it at m.slashdot.org and keep reading!

 



Forgot your password?
typodupeerror
×
Programming

Bad Programming Habits We Secretly Love (infoworld.com) 497

snydeq writes: Breaking the rules can bring a little thrill — and sometimes produce better, more efficient code. From the article: 'The rules are more often guidelines or stylistic suggestions, not hard-and-fast rules that must be obeyed or code death will follow. Sure, your code might be ridiculed, possibly even publicly, but the fact that you're bucking conventions adds a little bit of the thrill to subverting, even inadvertently, what amounts more often than not to the social mores of pleasant code. To make matters more complex, sometimes it's better to break the rules. (Shhhh!) The code comes out cleaner. It may even be faster and simpler.' What bad programming habits can't you (or won't you) break?
This discussion has been archived. No new comments can be posted.

Bad Programming Habits We Secretly Love

Comments Filter:
  • You're the problem (Score:5, Insightful)

    by U2xhc2hkb3QgU3Vja3M ( 4212163 ) on Tuesday October 20, 2015 @02:38PM (#50767347)
    If you think it's nice to break habits or do unconventional code just for the thrill of it, remember how fun it is when you need to work on someone else's code.
    • by tripleevenfall ( 1990004 ) on Tuesday October 20, 2015 @02:54PM (#50767479)

      “Any fool can make a rule
      And any fool will mind it.”

      Thoreau

    • by Anonymous Coward on Tuesday October 20, 2015 @03:17PM (#50767685)

      Back during Y2K updates to our code base, we'd occasionally have to deal with code written by an ex-employee, who we'll call John. It was so bad that every time someone opened a file he had worked on you'd hear a loud "FUCK! Another John file!" over the cubical walls.

      • Re: (Score:3, Interesting)

        by AmiMoJo ( 196126 )

        We had a contractor I'll call Paul. He wrote exactly to spec, and not a line more. If you didn't say "protect against buffer overflows when accepting user input" you can guarantee his code would crash if you input a single extra character beyond the prescribed format. It only worked if you did exactly what the user manual described. Any slight deviation and you were screwed, often in ways that were not immediately obvious.

    • by jellomizer ( 103300 ) on Tuesday October 20, 2015 @03:24PM (#50767747)

      We are hired to write new programs/new ways of solving a problem. Rules are made to solve common problems.
      If we only follow these rules we are limited to writing programs that have already been written, in that case we are just useless.
      If we know when to bend or break the rules, then we can create things that solve problems differently and is new and unique.

      When I work with programmers so are hard fixed on the right way to do things, I often get a response that x cannot be done. I break the rule and I have done it in a couple of days work, then they will go but you didn't follow the right form.
      The end user doesn't care about form, they care if it Works well, It can be maintained, and it is secure.

      • Re: (Score:3, Insightful)

        by Anonymous Coward

        You sound are one of the "men of some parts whose cleverness sets them apart from their fellows, but not nearly so far as they imagine."

        If we only follow these rules we are limited to writing programs that have already been written...

        Non sequitur, and nonsensical. All major programming languages are Turing-complete, and should all be able to express the same statements/programs.

        When I work with programmers so are hard fixed on the right way to do things, I often get a response that x cannot be done.

        There are things that are impossible in computer science, e.g. solving the Halting Problem. Most programmers tend not to conflate the impossible with the difficult or computationally expensive; your doing so is not a good sign.

    • by Dutch Gun ( 899105 ) on Tuesday October 20, 2015 @03:51PM (#50767941)

      I've heard arguments against writing proper comments similar to what the author makes: "but if you change the code and the documentation or comments don't change, then it might be worse than no documentation at all." My response is that if you're not updating the documentation or comments, then you're not finishing the job you were assigned. You could make the same arguments against taking the time to create meaningful variables and function names.

      There's another argument against comments I occasionally hear as well, which is "a competent coder should be able to discern what the code is doing without comments." While that's technically true, it's another argument I would reject. I feel the best comments can and should declare the intent of a block of code, rather than drilling down into the mechanics of the code. Those types of comments are often much more valuable than comments which simply regurgitate the mechanics of code in English.

      Still, in my own code, I don't have a fixed ratio of comment to code. It's entirely dependent on the complexity / obviousness of the code in question. For instance, if you have a very simple function, such as a handler that reacts to some UI event and just passes along the event to some other system, or performs a simple operation, it's stupid to spend a bunch of time and create excess visual noise to document that function. A quick glance at the code tells you everything you need to know about what's going on far easier than comment blocks.

      On the other hand, when code gets more complex, or the internal workings of a function is less than trivial, I expect to see a more comments in the code. In some of the most complex code I've either written or worked on, the number of lines of comments can actually exceed the number of lines of code. I've even seen some helpful little ASCII drawings in some particularly complex physics code, which was awesome.

      • Re: (Score:2, Interesting)

        by Hussman32 ( 751772 )

        My comment about comments in code is that all comments need a date and the coder's initials as a minimum, and old comments should not be deleted. I have way too much experience knowing why these are my comments.

        • by Jaime2 ( 824950 )

          If you need comments to know who wrote what and on what date, then you need to get your code into source control.

          • No, it's not about who wrote what, it's about "This is to satisfy requirement X", followed by "VP Blow wants the color changed", "VP Schmoe wanted it changed back" . . . .
            • Tracking when changes were made, and why, is the job of your source control system. Describing what the code does, is mostly the job of the code; variable names, function names and an occasional brief comment. Describing the expected inputs and outputs of the code is the job of unit testing. Describing the intent of the code, well that's a bit harder to get the right balance. Of course there's lots of overlap, and some huge grey areas.

              When reading someone else's code to track down a bug, or add a new featu

      • by rgmoore ( 133276 ) <glandauer@charter.net> on Tuesday October 20, 2015 @04:14PM (#50768125) Homepage

        I feel the best comments can and should declare the intent of a block of code, rather than drilling down into the mechanics of the code.

        Exactly. There's a lot of code that needs comments like "fixes bug XXX". If you had to fix a nasty bug and it took you a day to get the details right, let the next poor sap know what you were doing. Otherwise, he's likely to reintroduce the bug by tearing out this apparently useless code.

        Another good use of comments is to summarize a large block of code so that people don't have to dig into it to figure out what it does. For example, it's good to document functions at the top with enough detail that somebody would know how and when to call them without having to read through the whole thing.

      • There's another argument against comments I occasionally hear as well, which is "a competent coder should be able to discern what the code is doing without comments." While that's technically true, it's another argument I would reject.

        Me, too.

        Sure, a competent coder can tell what the code IS DOING. So can a compiler. That's not the issue. What do you do if what the code is doing is the wrong thing? What is the RIGHT thing? If all you've go is the code, you're hosed.

        NO process can look at code alone and

  • by PacoSuarez ( 530275 ) on Tuesday October 20, 2015 @02:39PM (#50767359)

    If the code comes out cleaner, you didn't break any of my rules. The rule "make the code as clean as possible" trumps all other rules.

  • It's a tradeoff (Score:5, Insightful)

    by plover ( 150551 ) on Tuesday October 20, 2015 @02:43PM (#50767385) Homepage Journal

    Sure, you can trade maintainability for efficiency and reliability. People do it all the time. You just have to understand the costs involved. If the efficient code gains you a million dollars in performance, maybe you can afford for it to be crappy code. Or maybe you'll be running the code for 10 years, and if it costs you $250,000 to keep a crusty old engineer on staff who can maintain it, suddenly that million dollars in performance may not be worth it.

    <disclaimer>I am a crusty old engineer.</disclaimer>

    • If you get the million right now that may be worth spending 2.5 million over ten years, if you're short on cash flow. Going bankrupt is bad.

  • by CAOgdin ( 984672 ) on Tuesday October 20, 2015 @02:43PM (#50767387)

    We ALL fully document our code, have clear specifications before we write code, use meaningful variable names and rely on IDEs...amirite?

    In my case, I only program (after doing it for pay for 45+ years) for myself, and I'm creating new stuff all the time, based on experience. For example, my backup strategy. It started out as a simple script to launch Drive Snapshot. It evolved, into having multiple, cascaded backups on one partition of the computer, which are replicated automatically to my main "server" in case the computer dies. Each computer in the office uses the same central repository. It's got bells and whistles that make my job a lot easier when I experiment...if I try some new app and it trashed Windows, I just roll back to last night's backup. (I believe in 100% backups of all computers...including the server...every night, and schedule "fixit/improve it" time first thing in the morning, so I can rollback and lose nothing.)

    So, personally, I now break all the rules, and let my needs dictate the code I write. It isn't specified, it's an evolving organism in my small environment.

    Oh, and I'm doing all that in cmd files...might consider upgrading to something exotic, like AutoIt, someday, but I've been saying that for four years now...

    • Re: (Score:3, Funny)

      by sconeu ( 64226 )

      I once saw source code for a library, written in Ada that had the following "feature".

      Since Ada code is "self documenting", each routine had a block comment documenting said routine. The block comment was LITERALLY a copy of the routine, commented out...

      e.g.:


      -- procedure body f is
      -- begin
      --TEXT_IO.PUT_STRING('Hello world');
      --TEXT_IO.PUT_LINE;
      -- end f;
      procedure body f is
      begin
      TEXT_IO.PUT_STRING('Hello world');
      TEXT_IO.PUT_LINE;
      end f;

  • Copy and Paste. (Score:5, Informative)

    by jellomizer ( 103300 ) on Tuesday October 20, 2015 @02:44PM (#50767395)

    Sometimes I will copy and paste a function and just do some minor tweaks were I could have just added a parameter.
    Why do I do this? Readability. Having a function called SplitPersonName(string name) and another one called SplitCompanyName(string name) So when I run the function it will be easily readable, as well if there is a bug in one of the fuctions but it works fine for the other. I can just change that one function without having to unit test other parts that could have been effected.

    Also I avoid too much Classes that are extended from other classes, that tends to add confusion on where a particular code is being called if you are debugging it from the middle of the class structure.

    It is OK to break rules, but you should have a good reason to do so. Also you should feel free to not break the rules when you do not have a good reason to do so.
     

    • Re:Copy and Paste. (Score:4, Insightful)

      by Junta ( 36770 ) on Tuesday October 20, 2015 @02:58PM (#50767519)

      Adding another variant, when you have an existing function that you never expected to reuse part of, suddenly interested in a twist on it. The 'proper' answer is to refactor so that it is shared code, but the code being reused is something that's not changed in 3 years and never had an issue under impressive load. So I could either refactor including changing working code, or duplicate. I'll duplicate. Now my duplicate may break out the relevant code so that if such a circumstance arise later, that the duplication won't happen twice, but I would rather a duplicate exist than risk any change to proven code.

      • Just put a note to yourself in both places where you copied the code that you DO have the function duplicated elsewhere, so if you ever have to change it in one place, you know to check and verify you do or don't also have to check it on the other place. A dev at my last job who duped some code that would create a PDF out of a Word document with mad-libbed bookmarks from the customer's file forgot to leave himself a breadcrumb trail. Took us two weeks to chase those bugs down until he remembered.
      • by jeremyp ( 130771 )

        This is the reason why you have comprehensive unit tests. You can refactor the original function safely in the knowledge that, if you break it, the unit tests will start failing.

        You do have comprehensive unit tests?

        • Re:Copy and Paste. (Score:4, Insightful)

          by readin ( 838620 ) on Tuesday October 20, 2015 @10:10PM (#50770469)
          Unit tests are no match for years of reliable service because for useful programs there is no such thing as a comprehensive unit test. One of the reasons computers are so useful is they can handle so many different input values - so many that you can't possibly test them all. Want to test a '+' operator for integers? Unless you run all MAX_INT * MAX_INT (oh way, I mean MAX_INT - MIN_INT+1 * MAX_INT-MIN_INT +1) possible inputs, how can you be sure you got everything? Well, let's just pick a representative test. Oh wait, we need to make sure we try with a negative number. Oh yeah, we need to a negative+negative, a positive+positive, a positive+negative, and a negative+positive. That it? Oh yeah we need to try negatives positives with zeros too. NOW we're done. What? OOHHH overflow! We need to write a test for two very large positive numbers and another for two very large negative numbers!

          That's just for simple integer addition. When you start writing real-life code the combinations of inputs grow very quickly. You do your best, but it simply isn't practical to test for every possible thing that could cause a problem.
    • Re:Copy and Paste. (Score:5, Insightful)

      by Junta ( 36770 ) on Tuesday October 20, 2015 @03:02PM (#50767549)

      Also agreed about too many classes. People think they make nice modular things by having short classes, but I just went through an exercise of pouring through about a dozen mind numbingly tedious files to find the single line of code that actually did something rather than just do a few pointlessly segregated checks or providing an alternative function for what '+=' already did or coercion into some datatype only to have it coerced back 'just in case' that middle layer might one day have another developer that would naturally think of it another way...

      • Envelopes stuffed into envelopes which are stuffed into envelopes, which are stuffed into manila folders which are stuffed into binders, which are stacked into cabinets, which have a security guard standing in front with orders to shoot anyone looking suspicious.

    • Re:Copy and Paste. (Score:5, Insightful)

      by CastrTroy ( 595695 ) on Tuesday October 20, 2015 @03:03PM (#50767561)

      For any rule you can come up with, you can probably find a valid case where breaking the rule would result in better code. Even GoTo can be useful in certain circumstances. Most of the good uses of GoTo have been codified using other key words. .C# has the continue [microsoft.com] keyword. It's basically exactly the same as using a GoTo to skip processing the current item. GoTo would have accomplished the exact same task, but people have such a dislike of GoTo that they had to create a whole other keyword that does exactly the same thing.

      • Re:Copy and Paste. (Score:4, Interesting)

        by PRMan ( 959735 ) on Tuesday October 20, 2015 @03:16PM (#50767667)
        But continue is very clear, as is break and return. Goto could go anywhere in theory, so it slows you down as you scan around looking for it.
        • The continue and break targets are clear enough in very simply code. They're much less clear when placed inside several levels of nested blocks. A goto statement has a named target you can easily search for, while the target of a break or continue statement is merely the end of the enclosing loop (or in the case of break, a switch statement). This may or may not be the same as the end of the current block.

          Besides the lack of a named target, this points out another drawback of continue/break: wrapping code i

    • Obviously you should have used the Factory Pattern in conjunction with the Strategy and Visitor Pattern. It would have been way more verbose, more complicated to read and probably a few cpu cycles slower per call, but you would have looked so much smarter :)
  • by PvtVoid ( 1252388 ) on Tuesday October 20, 2015 @02:44PM (#50767397)

    From TFA:

    my friend wired together an Eliza-like AI to his editor, and voilà, every function had a few lines of "documentation." The boss wasn't smart enough to understand that the lines meant nothing, so my friend was off the hook. His code was officially documented. I think he even got a promotion!

    He should have been shot.

  • by Anonymous Coward on Tuesday October 20, 2015 @02:46PM (#50767411)

    long methods - someone thought it a good idea to limit every method to no more than 20 lines. I think this is a terrible idea, and can make code unreadable, which leads to:
    coupling - it's often best to tightly couple things for ease of debugging and development. How often are you going to change the database you're using? Is it worth going through another abstraction for every database call? Too much abstraction makes code unwieldy.

    I'd rather have a bunch of 200 line methods that represent logical units of work than a call stack 20 layers deep.

    • by Junta ( 36770 )

      a call stack 20 layers deep.

      This here is my pet peeve of most 'modern' code projects, an insane call stack. Sometimes there's good reason, but often it's simply because the project is badly duct taped together rather than carefully thought out.

      Exacerbated in a lot of cases even more by having multiple over the network calls to chain several of these sorts of atrocities together. I have seen a team charged with being a sort of single middleware for a pretty straightforward sort of job self-create 4 distinct processes that each get in

    • long methods - someone thought it a good idea to limit every method to no more than 20 lines.

      Show them tcp_input(). After they have a heart attack at the number of pages it takes to implement the input state machine for the TCP protocol, bury them, and get on with your life.

    • by Dastardly ( 4204 )

      When I have run into long methods the solution usually is not a deep call stack, but instead that the method has chained together 20 10 line logical units. It would make the code more readable to have that be 20 sequential (not nested) calls to well named functions that accurately describe what they are doing. Often those logical units are different if/else blocks as well, so extracting them makes it easier to unit test all branches rather than trying to set up 200 different branch possibilities on one me

    • by coats ( 1068 )
      Two points: experimental, and cognitive
      Experimental:
      the evidence shows that the minimum bug-rate occurs for methods of somewhere between 300 and 500 lines. More than that and it really is too complicated to comprehend, most of the time. Less than that and you think "It's simple" and don't pay proper attention.
      Cognitive: magic numbers
      • 2 - 3 is the number of levels of recursion you can keep in your head at one time. Nested logic structures and call-stacks should never require you to look more than 3 l
  • GOTOs in C (Score:2, Interesting)

    by Anonymous Coward

    I often use GOTO statements in C code to mimic exception catching without duplicating cleanup code. It works very well, and its easy to understand, maintain, and debug. Example:

    x = do_stuff();
    if (x 0) { goto cleanup; }

    y = do_more stuff();
    if (y 0) { goto cleanup; }
    return 1;

    cleanup:
    fix_my_mess();
    fix_it_4realz();
    return 0;

    • Re:GOTOs in C (Score:5, Interesting)

      by halivar ( 535827 ) <bfelger&gmail,com> on Tuesday October 20, 2015 @02:50PM (#50767439)

      Comp Sci professors teach "goto = bad" because the wisdom necessary to use it competently comes only with experience. It's like jazz; you have to know the rules and follow them before you can break them and not sound like a jack-ass.

    • Re: (Score:3, Interesting)

      by PRMan ( 959735 )
      void cleanup()
      {
      fix_my_mess();
      fix_it_4realz();
      }
      ...
      x = do_stuff();
      if (x == 0){
      cleanup();
      return 0;
      }

      y = do_more_stuff();
      if (y == 0){
      cleanup();
      return 1;
      }
      return 0;
    • Re:GOTOs in C (Score:4, Insightful)

      by halivar ( 535827 ) <bfelger&gmail,com> on Tuesday October 20, 2015 @03:39PM (#50767847)

      So far we have 3 comments with the "right" way to do it that do nothing but add complexity and loss of readability for strict adherence to dogmatism imparted by our CS professors (few of whom had real-world programming experience).

      This is a straightforward problem. The suggested use of goto is a straightforward solution, and cleaner by far than the suggested alternatives. But most importantly, no one can demonstrate how it is wrong.

  • Dijkstra Nailed It (Score:5, Insightful)

    by myrdos2 ( 989497 ) on Tuesday October 20, 2015 @02:49PM (#50767431)

    In short, I suggest that the programmer should continue to understand what he is doing, that his growing product remains firmly within his intellectual grip. It is my sad experience that this suggestion is repulsive to the average experienced programmer, who clearly derives a major part of his professional excitement from not quite understanding what he is doing. In this streamlined age, one of our most undernourished psychological needs is the craving for Black Magic and apparently the automatic computer can satisfy this need for the professional software engineer, who is secretly enthralled by the gigantic risks he takes in his daring irresponsibility. For his frustrations I have no remedy......

    --Edsger W. Dijkstra

  • Lessons (Score:5, Interesting)

    by Tablizer ( 95088 ) on Tuesday October 20, 2015 @02:51PM (#50767443) Journal

    Variable and object naming, and commenting is an art-form that takes experience to do well. Here's a few practical guidelines I've learned follow:

    1. Think of newspaper headlines when commenting. Don't make somebody read the whole article to know what the article is about.

    2. Comment the "odd" stuff, not the obvious stuff infer-able from function name etc.

    3. Goldilocks Rule: Names both too long and too short can be bad.

    4. The more frequent a name is used, the shorter it should be. Use comments at declaration to give the full name. Example of a variable that may be used often:

    var dhv_id; // Department of Housing vendor ID

    If it's used often, I'd rather have an abbreviation than see DeptOfHousingVendorID all over the code, making it long and "wrappy".

    5. Everybody has their own preference, but you have to target the "average" developer (future unknown reader) to make code future-friendly.

    • by lorinc ( 2470890 )

      Nice ones.

      There's also a Goldilocks size for functions: functions too long are a pain to decipher, and it's easy to get lost between calls when all functions are too short. The same applies for OOP with the trade off between one Godzilla class and the Lasagna of too many classes.

    • Re: (Score:3, Insightful)

      I've been programming for quite awhile and honestly I'm in the verbose commenting camp.

      Not because I'm worried about code reviews, handing the code off to anyone else or even following some company's arbitrary rules on how things should be documented.

      I use verbose comments so I don't have to remember what was done and why it was done that way. Frankly I've got too many other things that I'd rather remember.

      Granted verbose comments will make my code seem pretty old school, but I have yet to hear any questio

    • Re:Lessons (Score:5, Funny)

      by internerdj ( 1319281 ) on Tuesday October 20, 2015 @04:15PM (#50768133)
      "Think of newspaper headlines when commenting. Don't make somebody read the whole article to know what the article is about." You_won_t_believe_the_three_things_this_method_does(), This_method_just_announced_it_was_running_for_the_GOP_presidential_nomination(unsigned int year), Five_ways_to_make_your_integers_long(), ...
  • by xxxJonBoyxxx ( 565205 ) on Tuesday October 20, 2015 @02:55PM (#50767487)

    Just one extra (or fewer) space per bracket...'cause I know it's driven SOMEONE nuts at every shop I've worked at.

  • Many of the rules in the article are about making the code easier to understand for yourself or whoever takes over when you have to leave a job or role. For example, you could put every single commands into one line; heck the entire program could be one really long line. I would argue it would be more efficient on disk space, but if you had to debug or modify it, it would be a mess. I don't code much but when I have to look over what I've done a year or two later, it's easier on me if I followed those rul
  • I love to use the ComeFrom statement [fortran.com]. It just makes the logic of the program so much easier to follow when others need to apply that very rare patch to my code.
  • Since when is returning from the middle of a loop a bad thing? I've never been taught that, and it certainly hasn't been a guiding principle in any code base I've worked in.

    • Combine that with another poster's 200-line methods and someone looking at the code has no easy way to know what the code returns - what it DOES . And the person looking at it my be you in two years. Also, such code -lies- about what it does. More on that in a minute.

      It is better to return at the bottom of a function, partly so you can FIND the damn return statement. So an improvement over return () in the middle of the function is to break.

      Even better, make the loop condition honest. Instead of this:

      w

    • I think it's an extension of best practice having only one return in a function... which I kind of agree with since it works into your try catch loop. If you need more than one you probably need to split break up your method into more than one function

    • by PRMan ( 959735 ) on Tuesday October 20, 2015 @03:25PM (#50767751)
      He's still trotting out "rules" that were in vogue 15 years ago. Break, continue and early return are clean and inserted into every programming language eventually.
    • by Yunzil ( 181064 )

      There are a lot of people out there who subscribe to the "single point of exit" theory, meaning all your code paths through a function should lead to the same return point.

      I am not one of those people.

  • #3 (overly long lines) largely depends on the language you write in. SQL, for example, pretty much forces you to either write far-too-long lines, or to use tediously tall vertical layouts. The former lets you focus on the bigger-picture logic of a procedure, while the latter only matters if you care about quickly knowing the 10th field returned in a given selection.

    For #6 (reinventing data structures), gimme a frickin' break - I will not pull in a 3rd party library just to implement a data structure I c
  • sometimes it's easier to cut 'n paste than trying to paramaterize everything -especially early on when your banging out a quick report of proof of concept

    -although if/when I end up doing parameterization I have to hunt through the code and delete all the stuff that was obsoleted by the parameterization

    -I'm just sayin'
  • There are a lot of bad "rules" running around out there. There's also a lot of good ones. Some have evolved through painful experience; others are more like cargo-cult beliefs. But the bottom line is that we're all terrible judges of our own work. That's why authors need proofreaders and (frequently) editors. If you want to break something you think is a rule, for whatever reason, try checking with your cow-orkers, to see what they think about it. Yes, they may all be hide-bound idiots, but if you get hit b

  • The longer or more descriptive the variable name, the wider the scope.

  • by anyaristow ( 1448609 ) on Tuesday October 20, 2015 @03:35PM (#50767823)

    It seems that many in the field these days are afraid to code something themselves for fear that someone will find fault. So, they do things "the established" way, which is generally frameworks or anything that can be called "reusable", even if this generation's "reusable" is always less reusable than last, because it keeps getting needlessly more complex to the point that nobody *can* reuse it.

    Used to be programmers had a fault we called "not invented here", in that they'd insist on re-writing things that already existed, because it was easier to understand their own code than to use someone else's. These days it's reversed. For fear of criticism, they *must* use someone else's code rather than write their own. I call it "afraid to invent it here."

  • I see a lot of rigidity around buzzwords and established practice, because programmers these days are given tools, and to appear smart to other programmers, they treat these tools as rules. As if knowing some rules is more important that solving problems and getting the job done. It's apparently easier to show how smart you are by regurgitating rules and criticizing people who don't follow them rigidly than it is to actually accomplish things.

Do you suffer painful elimination? -- Don Knuth, "Structured Programming with Gotos"

Working...