When To Write Bad Code
brandonsavage.net
brandonsavage.net
It allows you to get to grips with the problem and prevents you from just copy-and-pasting large chunks of the "i'll rewrite this later" code into production.
I tend to write my prototypes in Perl as I used to use it a lot in the past for hacking things together. It translates well both to Ruby on Rails (front end) and to C (with low level server magic).
Love this quote. I assumed it was an existing quote/idiom, but it looks to be original.
I write dozens of shell pipelines every day. Some graduate to actually being saved in files and cleaned up a bit. Some of those start needing new features, and end up rewritten as quick and dirty perl scripts. A few of those see constant use in more and more circumstances and end up accumulating an ever larger number of features. Once that program grows large enough, it'll become obvious that it'll become unmaintainable at some point. And you can either evolve that code into a less crappy state when other changes are made, or you can rewrite it from scratch.
And the thing is, you can't really know in advance what kind of a program a given problem really warrants. Is it shell pipeline that'll only ever be run three times, or will it end up as a core component of somebody's workflow. Since you can't predict these things, you have to play the odds. If most programs end up as important tools, it'd be insane to risk the need of multiple rewrites. While if most programs end up just gathering dust somewhere, it'd be insane to polish them to perfection before committing. And even if "nothing lives longer than temporary code" is a nice soundbite, I don't actually believe that for a moment. I'd bet that most temporary code actually dies almost instantly. It's just some kind of observation bias.
However, I've only seen it work in practice when you do go back and refactor. Too often the smelly code gets left behind, and that is why I usually ask others to think through code before writing.
Amen. Nothing beats the instructive facility of running code and a usable UI.
> However, I've only seen it work in practice when you do go back and refactor. Too often the smelly code gets left behind, and that is why I usually ask others to think through code before writing.
Well, of course it won't work if you don't refactor. You get results analogous to writing with no revision. There's also the trick of knowing when you've revised enough -- amateurs stop before the pros.
I find "write working code & then refactor" ridiculously easy when working with Git. Add some tiny new things one-by-one and commit early each time it is more or less stable (so you can revert quickly when you screw it later, instead of doing some crazy debugging). When it's done, squash the commits and refactor.
My current project contains some non-trivial code so there was a lot of prototyping. If I spent time ensuring this code was also well written, I doubt the problems would've been solved because half of my energy and concentration would be spent on scaffolding and not the actual building.
Having said that, I still find documenting the prototype as important as real code. When it comes to refactoring the code, it helps a lot.
After coding the first implementation you will always realize things that you didn't anticipate that could improve the design. It's easier to get it working quickly, find the holes in the algorithm/design, then refactor it to be pretty and maintainable.
In the end it depends whether it's easier to just code or setup scaffolding (ie, TDD tests) to then write the code.
It may be unelegant, it may lack any number of "best practices", but if your code solves a problem, doesn't break other things, and can be refactored effectively, it doesn't count as bad.
I disagree that writing "shit code that still works" and TDD have to be mutually exclusive. In fact, if I'm going to go the "just get it done" route, I will almost (but not always) try to set up a few tests for it.
Because nothing sucks harder then going back to crap code and trying to decipher what it's doing. If it's crap code, then it's likely non-orthogonal code, which means changing it will likely break something...etc. etc. Tests help me do the refactoring later.
And, also, how do I know that my shit-code-just-works actually works? Sometimes, it's helpful to write a kind-of-shitty-test to at least verify that it kind of works, if not perfectly.
In most cases though, I agree with you.
Some people can visualize an entire program in their head and how it will interact. Not me. I hack at the core of the problem I'm trying to solve, until I've solved it. Then I reorganize the code into something that (hopefully) isn't crap. It seems inefficient, but it works for me.
The RSpec book is a pretty good introduction to this topic.