26

A while ago, I asked a question on SO about something written in C++, but instead of getting an answer to the problem at hand, the comments went all crazy on my coding style, even when I indicated that it was a WIP piece of code and that I meant to clean it up later when I had the base case running. (I got so many down votes that I decided to pull the question, as my rep on SO already is near-abysmal)

It made me wonder why people adopt such a hard line "you're a noob, go fuck yourself" attitude. I was being accused of writing C++ as if it was Java. Something that I cannot understand, and that still baffles me.

I've been programming in quite a few OOP languages for a number of years now, albeit in intervals. I choose the language to use in terms of its available libraries and optimal execution environments for the job at hand. I adopt design patterns in OOP code and I'm quite confident that my use of patterns is sound and that OO wise, I can hold my own. I understand the OOP toolbox, but choose to use the tools only when I think it's really required, not to just use a neat trick to show my coding wits. (Which I know are not top notch, but I think aren't at n00b level either).

I design my code before I write a single line. To define tests, I list the goals of a certain class, and the test criteria that it has to adhere to. Because it is easier to me to create sequence diagrams and then write code, I chose to write my tests after the interface has become obvious.

I must admit that in the piece of code I posted in the question, I was still using pointers, instead of using smart pointers. I use RAII whenever I can. I know proper RAII means safeguarding against nullpointers, but I work incrementally. It was a work in progress and I meant to clean it up later. This way of working was condemned strongly.

In my view, I should have a working example first so I can see if the base case is a viable way of thought. I also happen to think that cleaning up the code is something that is typical of the refactoring phase of agile, after the base case has been proven. I must admit that although I'm slowly getting the Cxx standard, I prefer to use what I understand, instead of taking the risk of using concepts that I have yet to master in production code. I do try new stuff once in a while, but usually in play projects that I have on the side, just for that purpose.

[edit] I'd like to clarify that gnat's suggestion [1] did not show up in the search I did before I started to ask my question. However although his suggestion does cover one aspect of the question, the question he linked to does not answer the heart of my question, just part of it. My question is more about the response I got to my coding style and the professional aspects of handling different coding styles and (apparent) levels of skill. With my previous question on SO and it's response as a case in point. [/edit]

The question then is: why scoff someone that doesn't use your coding style?

The matters/subdivisions at hand for me are:

  • Why would it be a bad programming practice to use more error prone code in prototype situations, if refactoring makes it more robust afterward?
  • How would can program written in C++ be like it was written in Java? What makes it a bad program, (considering that I indicated the intent of the current style and the planned work to improve?)
  • How would I be a bad professional if I chose to use a construct that is used in a certain programming paradigm (e.g. OOP/DP)?

[1] Develop fast and buggy, then correct errors or be slow, careful for each line of code?

Onno
  • 1,523
  • 1
  • 12
  • 18
  • 5
    You might be better off asking the folks in The C++ Lounge this question. Put on your flame-proof suit first. – Robert Harvey Mar 26 '14 at 16:18
  • 1
    That's exactly why I asked it here. I could just as well replace C++ for another type of OOP capable language, and run into the same argument. I took a real world example, but it doesn't have to be C++. It's just as much a technical question, as one of professional attitude. – Onno Mar 26 '14 at 16:21
  • 50
    C++ folks are an unusual breed among programmers. Your Java toolkit is a sensible, well-understood tool box with familiar tools in a padded leather case that will work in any tool shop. C++ is an entire toolshed with a rip saw, a power drill, and some tools that nobody recognizes, all of which the C++ crowd can handle like ninjas. It distresses them when someone comes in and puts some tool back on the shelf in the wrong place. They're the "measure twice, cut once" of programmers. – Robert Harvey Mar 26 '14 at 16:24
  • possible duplicate of [Develop fast and buggy, then correct errors or be slow, careful for each line of code?](http://programmers.stackexchange.com/questions/99980/develop-fast-and-buggy-then-correct-errors-or-be-slow-careful-for-each-line-of) – gnat Mar 26 '14 at 17:20
  • 1
    Gnat, I can see how that would be a possible duplicate, but I feel that my question is much more about the response. I feel that you're zooming in on just one aspect. – Onno Mar 26 '14 at 17:23
  • http://meta.stackexchange.com/questions/194476/someone-flagged-my-question-as-already-answered-but-its-not – gnat Mar 26 '14 at 17:27
  • @gnat : I assume that you're pointing to the answer, not the question you've linked to? I'll rework the question – Onno Mar 26 '14 at 17:32
  • Could it have been a case of "write Pascal/Fortran/Java code in any language"? – Bart van Ingen Schenau Mar 26 '14 at 17:34
  • @bart-van-ingen-schenau that's why the title doesn't refer to C++ and java explicitly. – Onno Mar 26 '14 at 17:35
  • 14
    If you write C++ like Java, you will likely end up with way too many heap allocations, which will make your program perform more poorly than it could. Languages tend to be designed and optimized to promote certain patterns, and if you break those patterns, things will tend to go worse for you. – Gort the Robot Mar 26 '14 at 19:05
  • 13
    Maybe it's the same reaction you would have to Java code that was written like FORTRAN: all code in a single class, no collections, only fixed-size arrays, with separate `int` variables to keep track of the actual length. – kevin cline Mar 26 '14 at 16:39
  • 5
    You posted code online to get some form of help. I realize you didn't want/expect all the feedback on your style, but would you prefer no help at all? You take the good with the bad. Programmers have to look for faults in code; it's what we do. – JeffO Mar 26 '14 at 19:56
  • 1
    Can we get a link to the original question? – Chuu Mar 26 '14 at 21:02
  • @Chuu He said he deleted it, but perhaps a sample of that code? – Izkata Mar 26 '14 at 21:25
  • 2
    C++ is like a nuclear reactor. If your code is built nice and safely, it's a greatly performing tool. If you've just hacked it together using the knowledge you got from coal fired power plants or your nice hydroelectric dam, you might find out that forgetting one `*` or `&` causes your computer to explode. Nuclear engineers tend to be way more cautious than the others (and other civil engineers tend to be way more cautious than software engineers :D), because "fixing the issues later" might not be possible or practical. Good C++ programmers have to be very disciplined. – Luaan Mar 27 '14 at 09:10
  • 2
    This isn't a question, it's a complaint about another question. You asked people to help you, and now you want to vent because you're not happy about what they said. This belongs on your blog. – jwg Mar 27 '14 at 10:25
  • 1
    Somewhat related ;-) [Write program in your favorite language in another language](http://codegolf.stackexchange.com/questions/24623/write-program-in-your-favorite-language-in-another-language) (note: that's a joke) – Uooo Mar 27 '14 at 13:41
  • @JeffO I thought that by indicating that I knew that I was aware of the pointer issue, I could let people understand that I was aware of that pitfall, and leave it at that. Unfortunately, the opposite happened. The question itself got no attention whatsoever, as far as I can remember. (unfortunately, I can't look it up, so I have to go on my memory here) – Onno Mar 27 '14 at 14:21
  • @jwg A part of the question would have had a better fit in meta.SO if it was really about the gripe. However, my question is one of behaviour, not technique itself. It does feature a technical part as a case in point. I hope you can see that distinction. – Onno Mar 27 '14 at 14:22
  • I understand the distinction, but I still don't accept that you are actually asking a question. – jwg Mar 27 '14 at 15:10
  • 4
    "I know proper RAII means safeguarding against nullpointers" -- You know what's more dangerous than not knowing? Not knowing and believe to know. The RAII acronym means "Resource Acquisition Is Initialization" and is an idiom to manage allocation and deallocation of objects or, in a more general sense, resource management. RAII can theoretically be applied even to resources that are not dealt with with pointers (such as VBOs in OpenGL). So yeah, just wanted you to know that, even though RAII can be often seen next to pointers, they are definitely two different things. – Shoe Mar 27 '14 at 15:41

5 Answers5

44

Each programming language has a set of idioms and best practices, which will usually lead to elegant, correct, and performant code. Here are a few worst-practices that are perfectly fine in some other language:

  • I will yell if you write for ($i = 0; $i < 42; $i++) { … } in Perl, but not in PHP
    (in Perl, variables should be declared, and such loops should iterate over a range)
  • I will weep if you write new Foo() in C++ without good reason, but not in Java
    (C++ doesn't have garbage collection, so RAII should be used. Noobs will leak memory otherwise)
  • I will cringe if you declare all your variables at the top of your function, except in C89, Pascal, or JavaScript.
  • I will facepalm if you put all your functions into a class in Python, but not in Java
    (Python is a multi-paradigm language instead forcing “OOP” and supports functions at the top level)
  • I will cry if you return null in Scala, but not in any C-like language
    (because Scala has an Option type)
  • I will complain if you write a recursive algorithm in Java, but not in OCaml
    (because Java's stack overflows quickly, whereas OCaml has tail call optimization)

It is easy to use a new language as if it were something you know, and with luck it will even work. “You can write Fortran in any language”. But you really don't want to ignore the specific features language X offers, because chances are good that X offers some advantage over U.

I choose the language to use in terms of its available libraries and optimal execution environments for the job at hand” – but whether this language X is actually better than language U for the job at hand also depends on how familiar with that language, or how long it will take to get sufficiently familiar in order to use it well. You wouldn't yield a heavy chainsaw just because it cuts wood fastest, when you actually want your old pen knife because it fits into your hand perfectly. Unless you actually want to fell a tree.

But your question is more about a cultural issue: learning all best practices takes a lot of time, and newbies ask the most questions, whereas gurus answer them. But what is obvious to a guru is not obvious to a newbie, and gurus sometimes forget that. As a newbie, the solution is not to stop asking questions. However, one can show an openness to learn and apply best practices, e.g. by trying to clean up your code as much as possible before showing it to others. Most languages have a few core best practices which are easy to learn, even when the whole learning curve is actually very long.

A common problem is that people new to programming disregard any indentation or other formatting, and then are confused because their program doesn't work. I would be confused as well, and the first step to understanding a program is making sure it's perfectly layouted. Then, simple errors like a forgotten closing quote or a missing comma suddenly become obvious. I trust that you already practice good formatting, and here it's a metaphor for other best practices: best practices prevent errors, best practices make finding errors easier, applying best practices comes before finding the problem.

It is too cheap to say “I'll fix it later”, when fixing it now would have solved your problem (also, that fabled “clean-up phase” may never come, so the only responsible option is to do it right the first time). At the very least, trying to make your code as good as possible before asking others for help makes it easier for them to reason about your code, so is the polite thing to do.

amon
  • 132,749
  • 27
  • 279
  • 375
  • You're quite right on some of the points you make, but in the end I don't think you're hitting the mark. You're assuming the attainment of knowledge before having the experience that will gain the knowledge. – Onno Mar 26 '14 at 19:00
  • 5
    @Onno My main points (which do answer the questions you asked) are that you can't carry over habits from one language and assume that it's a best practice in another, and that trying to write clean code from the start is preferable to cleaning it up later. Cleaning up code – to the best of your ability – is a must before asking others for help (see http://www.sscce.org/ for tips on good code snippets). Dumping rubbish code on SO with a “please fix this” is unacceptable especially if you know better. – amon Mar 26 '14 at 19:25
  • 2
    But regarding the question you are hinting at: [jm666's answer](http://programmers.stackexchange.com/a/233813/60357) contains a key point: the guru thinks “why would you ask about X if you didn't want to become an X-guru yourself?” I find myself too often in this unhelpful mindset. A possible way to defuse that is to mention that you still are at the very beginning of the learning curve and will look into that later, but for now have this more immediate question at hand. However, that's a communication problem, not a programming issue. – amon Mar 26 '14 at 19:25
  • 7
    Both C++ and C# have `optional` and `Nullable` respectively. Also, practically *everybody* leaks memory in C++ without RAII, noob or not. – DeadMG Mar 27 '14 at 14:17
  • I find that declaring variables at the beginning of a block usually makes your code a easier to read in most languages. This way you know exactly where to look when you need help remembering which types all of your variables are and such. –  Jan 12 '15 at 01:36
26

Without seeing the code in question, there are a few ways to write Java code in C++, some worse than others.

  1. At the one extreme, there's laying out your source like Java: everything in one file, everything within the class definition, etc.:
    class HelloWorldApp {
    public:
        void main() {
            cout << "Hello World!" << endl;
        }
    };
    
    This is how Java source would be laid out. It's technically legal in C++, but putting everything in the header file and everything inline (by defining it in the class declaration) is terrible style and will kill your compile performance. Don't do it.
  2. Excessively OO - To oversimplify, in Java, it's the Kingdom of the Nouns, where everything is an object. Good (i.e., idiomatic) C++ code is more likely to use free functions, templates, etc., instead of trying to cram everything into an object.
  3. No RAII - You already mentioned this - using pointers and manual cleanup instead of smart pointers. C++ gives you tools like RAII and smart pointers, so good (i.e., idiomatic) C++ code uses those tools.
  4. No advanced C++ - The basics of Java and C++ are similar enough, but once you get into more advanced features (templates, C++'s algorithms library, etc.), they start to diverge.

Except for #1, none of these make a C++ program a bad program, but it's also not the kind of code I prefer to work on as a C++ programmer. (I also wouldn't enjoy working with non-idiomatic or C-style Perl, non-idiomatic Python, etc.) A language has its own tools and idioms and philosophy, and good code uses those tools and idioms instead of trying to use the lowest common denominator or trying to reproduce another language's approach. Writing non-idiomatic code in a particular language / problem domain / whatever doesn't make someone a bad programmer, it just means that they have more to learn about that language / problem domain / whatever. And there's nothing wrong with that; there's a very long list of things I have more to learn about, and C++ in particular has an absolute ton of stuff to learn.

Regarding the particular question of writing error-prone code with the intent to clean it up later, it's not black and white:

  • If some prototype code fails to handle every possible exception and every possible corner case, then that's to be expected. Get it working, then get it working robustly. No problem.
  • If some prototype code is written in what's simply a bad style or a bad design (bad for the given language and its idioms, a fundamentally bad design for the problem, etc.), then unless you're writing it as a throw-away proof-of-concept, you're not gaining anything.

To use raw pointers versus smart pointers as an example, if you're going to work in C++, using RAII and smart pointers are fundamental enough that it should be faster to write code that way than to go back and clean it up later. Again, failing to do this doesn't mean someone's a bad programmer, unprofessional, etc., but it does mean there's more to learn.

Josh Kelley
  • 10,991
  • 7
  • 38
  • 50
  • 11
    there is idiomatic perl? – ratchet freak Mar 26 '14 at 16:44
  • 3
    @ratchetfreak - Sure. Compare C-style Perl that uses nothing but `if` blocks and `for` loops with Perl that uses `Modern::Perl`, regexes, `if` and `unless` one-liners, etc. – Josh Kelley Mar 26 '14 at 16:46
  • 5
    before you even get to RAII though you want to consider if you need to use new at all, using dynamic storage if you can use automatic storage is just making more work for yourself – jk. Mar 26 '14 at 16:52
  • Thank you for your great answer :) I do keep wondering though: Why do people insist that everyone uses the full toolbox if those tools can just as well complicate things to the point where using them is making things harder to solve problems? (Im thinking of #2, but even more of #4) – Onno Mar 26 '14 at 17:17
  • 22
    @Onno When you ask *"How do I hammer this screw into the wall without it getting bend?"* everyone will tell you not to use a hammer. – Sjoerd Mar 26 '14 at 17:24
  • And why use a powertool when a handtool can do the job just as well? – Onno Mar 26 '14 at 17:26
  • 10
    @Onno In C++, pointers and `new` are considered the powertools. Automatic storage is the handtool. – Sjoerd Mar 26 '14 at 17:28
  • Not when I learned it at my college 12 years ago. I have to acknowledge that things were different today, and that I haven't kept up that much. Especially with Cxx. I'm adapting, but slowly. – Onno Mar 26 '14 at 17:30
  • 11
    @Onno: You have to realize that C++ programming courses tend to lag in their adoption of modern idioms and what is considered good C++ also has evolved enormously since C++ was invented. – Bart van Ingen Schenau Mar 26 '14 at 17:39
  • 6
    @Onno - The thing is that saying "this just complicates things, using it makes it harder" is only really possible when you're on the "I don't know that yet" side of the learning curve. From the perspective of people who have already learned, using it is simpler and easier, and it goes against learning and experience to not use it. (This is true in lots of fields; see [here](https://sites.google.com/site/steveyegge2/practicing-programming).) Sometimes you just need to suck it up and learn it; that's why I tried to emphasize the importance of recognizing when you have more to learn in my answer. – Josh Kelley Mar 26 '14 at 17:47
  • 1
    @Onno - With that said, there's nothing wrong with saying, "I don't have enough time to learn this subject right now," as long as you recognize that it may put you on the outside relative to the regular practicioners of a field. And there may be nothing wrong with saying, "I'm consciously choosing to not use a particular area" - like C++'s template metaprogramming - "because its complexity and learning curve aren't worth it." However, even making that call requires _some_ learning. – Josh Kelley Mar 26 '14 at 17:47
  • @BartvanIngenSchenau I do recognise that C++ is a changing language these days. I haven't kept up with the latest developments. And although I'm working on that (the side projects part), I can't always see the use of spending time to get up to date with the latest hype or another tool if I already have a tool that does the job. (I wanted to clarify my comment, so I chose to replace it. Sorry for the time/flow inconsitency) – Onno Mar 26 '14 at 17:49
  • 8
    Because of C++'s history, and the huge number of coders who learned the language before many of the more advanced features of the language appeared, there's a lot of crappy C++ out there still being written by people who write like they did a decade ago. The tetchyness about things like RAII are about getting everyone to use the modern methods so that we can stop seeing the same predictable failures. – Gort the Robot Mar 26 '14 at 19:16
  • 8
    FWIW RAII was not new in 2002. RAII is one of the two features that sets C++ apart from other languages and skipping it when teaching was already negligent in 2002. It's not C++ from a decade ago. It's C++ from people whose knowledge was already hopelessly outdated a decade ago. – R. Martinho Fernandes Mar 27 '14 at 08:41
  • 3
    Neither templates nor standard library is "advanced" C++. – Cat Plus Plus Mar 27 '14 at 09:32
  • 2
    I agree with @Steven: it stems predominantly from an overwhelming sense of frustration and _helplessness_, caused by the endless tide of antiquated/buggy/hard-to-maintain pseudo-C++ that just keeps on a'comin'. – Lightness Races in Orbit Mar 27 '14 at 12:10
  • 1
    @CatPlusPlus: Everything's relative; they are advanced compared to not using them. – Lightness Races in Orbit Mar 27 '14 at 12:11
12

I'm not a hardcore C++ developer, but...

Why would it be a bad programming practice to use more error prone code in prototype situations, if refactoring makes it more robust afterward?

One thing to keep in mind is that an error in C++ usually means "undefined behavior". In a safe language the worst that could happen is an exception terminating your program immediately. In C++, you're lucky if you get a segfault. It's entirely possible your program keeps going doing something subtly wrong. It could also behave correctly for a period of time and manifest bugs much later, or it could behave correctly all the time but eventually eat up all your memory.

In any case, it only takes a single mistake to take program execution completely off the rails and into uncharted territory. It's likely that for the full-time C++ developer, the "base case" means "no possibility of undefined behavior or memory leaks."

How would can program written in C++ be like it was written in Java? What makes it a bad program?

I don't think there's an answer to this that won't be largely speculatory and opinionated. If you want my take on it though, Java tends to have a couple of antipatterns associated like the fact that everything has to be an object. Where in other languages you'd pass a pointer, functor, or function, in Java you usually find tons of vacuous and narrowly-useful ThingDoers, FooFactories, and IFrobnicators which are just functions in disguise.

Likewise, where in other languages you might pass a simple tuple or nameless struct, in Java to bundle up even just 2 objects into a simple data container requires you to predefine a 30+ line NamedThing class with setters, getters, and Javadocs. Java's relative lack of features forces programmers to do object-oriented double backflips to get things done sometimes. The resulting code is rarely idiomatic outside of Java.

Then there's the fact that in C++ you need a very simplified object graph to manage memory manually; usually an object is owned by exactly one other object. In Java you don't need to follow such tight constraints, because the garbage collector ensures things will get cleaned up when there's no more references to them. So there's definitely a risk of incorrect memory management if you just transliterate code from Java to C++.

Finally, it could just be elitism. I won't pretend they make up the majority, but I've definitely seen a sentiment of "I don't need a language that'll hold my hand and keep me from doing stupid things" amongst some C++ developers. In their minds C++ is a "real" language and if you can't handle its idiosyncrasies you're not a "real programmer".

Doval
  • 15,347
  • 3
  • 43
  • 58
  • 1
    Much of this is alleviated with Java 8 - Lambdas rides in to *mostly* save the day :-) – Martijn Verburg Mar 26 '14 at 17:28
  • @MartijnVerburg Agreed, huge step forward there. But technological problems are the easy ones to fix! Old habits die hard and stigmas even harder. Heck, some people will go so far as to complain Java doesn't need any of these "new" features, and that it's en route to becoming the next C++. – Doval Mar 26 '14 at 17:40
  • Yeah I always shake my head at that - Java *will* deliberately always evolve more slowly than other languages as it's a long term workhorse. The JVM however can jump forward in leaps and bounds somewhat faster, which is what enables things like Lambdas to eventually come to the language. – Martijn Verburg Mar 27 '14 at 10:25
6

Slightly off topic answer...

Don't worry - this is a common "behavior" in any expert community. And be honest, if you're good in any language, and you will meet a code what is "strange", probably you will criticizing it too. (because, want TEACH).

I'm in the perl-world - when will see something like:

$imax=$#array;
$str=""
for($i=0; $i<$imax; $i++) {
    $str = "$str" . $array[$i];
}

instead of:

my $str = join '', @array;

sure will comment it - (read: teach the author) about the join function.

Anyway, too much criticism is counterproductive at all, and one of the best example is the next: (grabbed from: http://perl-begin.org/humour/#How_can_I_switch_off_the_T.V..3F)

(This bit was posted anonymously to a pastebot on 23 March, 2011. It is placed here for posterity after some editing.) - slightly edited too

Question: how can I switch on my TV?

What the OP wants to hear?

For example: Locate on/off button your TV remote a press it. The button is usually red and located at the topmost line on the remote.

The #perl expert's answer: First, what do you mean with "switch on"? Define it first. Nopaste your TV, TV remote and the living room too.

... after a nopaste:

Your room is ugly. And the TV looks terrible. Use Mr. Clean on the screen, and clean your living room first. Use three cleaning mops instead of two. Use HDMI and never use scart (?) connectors, unless you really want to. Your TV remote has unreadable buttons, clean up first. You're a beginner, so read:

http://experts.blog/how_to_design_a_future_3D_TV.html http://experts.blog/the_basics_of_tv_repairing.html http://experts.blog/viruses_in_living_room_short_essay.html http://experts.blog/global_chip_replacement_guide.html

IRC guest: But, i don't want be a TV expert.

Answer: Why do you want to switch the TV on then?!

clt60
  • 276
  • 1
  • 3
  • 11
  • 1
    This answer is **not** off topic. It explains exactly why someone would criticise unconventional use of a language, and why occasionally that automatic criticism may go too far. I like it. – trichoplax is on Codidact now Mar 28 '14 at 22:08
1

Why would it be a bad programming practice to use more error prone code in prototype situations, if refactoring makes it more robust afterward?

When writing quick and dirty with the mind of fixing later there is the danger of forgetting something that you need to fix.

How would can program written in C++ be like it was written in Java? What makes it a bad program, (considering that I indicated the intent of the current style and the planned work to improve?)

In java you don't have to think about who owns a certain object, you just pass the reference along and forget about it like it is nothing. However in C++ there needs to be a clear definition of who owns the object and who is responsible for cleaning it up.

How would I be a bad professional if I chose to use a construct that is used in a certain programming paradigm (e.g. OOP/DP)

You wouldn't; C++ is a multi-paradigm language, it happens to support OOP rather well but it can do a lot of other things as well. However most of it boils down to using the correct tool for the job instead of pulling out the hammer each time you need to drive a pointy spike into some wood.

The reason you got a bad response is that most people on SO tend to judge skills by how idiomatic you can code in the language you are asking about. The people familiar with C++ tend to knee-jerk when they see bad code that looks like something that has bitten them in the past.

ratchet freak
  • 25,706
  • 2
  • 62
  • 97
  • I can see that the forgetting to improve could be an issue for some, but I keep a long list of tasks, and I'm very disciplined in adding todo tags for these kind of jobs. (that's why I like VS, it is quite good at work management) It is the same for the documentation. I don't write a line of code before I've written the documentation for it. As for the ownership question, because of the sequence diagrams, I think that I do have a good idea of who has links to whom. – Onno Mar 26 '14 at 16:36
  • 1
    @Onno: Frankly, no one knows or cares how good *you personally* are at keeping track of that stuff. The vast majority of people that write C++ that looks like Java or C, are not even nearly so meticulous. It's far better for them to learn to do stuff right the first time than write themselves a note to go back and fix it later, because experience shows they practically never actually do it. – cHao Mar 26 '14 at 17:50