Write code like you just learned how to program
prog21.dadgum.com
prog21.dadgum.com
Now that I've been programming for over a decade professionally, I've accumulated a lot of practical experience. On balance this makes me a better programmer, but it also makes me worry more about everything: maintenance, bugs, version upgrades, etc. Wrestling with all possible issues can be paralyzing. Often it's better to just get something done, even if your future self will claim how much better it have been if it was done "right" in the first place.
I keep wanting to learn Ruby/Rails (and I have been working my way through the Rails Tutorial book online, albeit with a break the last week or so for travel and stuff). At the same time, I keep thinking "You know, I have so much domain experience with C# and ASP.NET, so would it be a better use of my time to focus on learning ASP.NET MVC and improving my architectural skills?"
I'm still working through that, but in the mean time, I'm pushing myself to at least go through the Rails tutorial (and probably an all-day Rails session at the CodeMash precompiler day) on the grounds that it's probably a good thing for me to break out of my narrow MS tech focus and gain exposure to other ways of doing things.
I think the only real constant in this field is that if you're not continually learning something, you're falling behind.
It happens so often that after I switch technologies, and then return after awhile I have a "wow it is so much easier to do it this new way" feel. Creative thinking is fundamentally a "combine and use old stuff in a new way", which means that learning new technologies is worth it just because of the new ideas, and if you can later use those technologies themselves - well thats just a bonus.
Anyway, the original comment is right on the money. I often have to tell miself "just write the damn stuff and refine it later" when I get mentally stuck thinking about ways in which it could break.
I learned Japanese, but when speaking it, I'm often hesitant. I used to hang out a lot with native speakers when I was younger, and there seems to be nothing middle-aged Japanese guys love more than seeing young men drink. After a few drinks, you stop second-guessing yourself, and so when speaking, words just came out, and my coworkers began laughing when, after I had spent all day stuttering and pausing, I would start spitting out fluid sentences. (A few more and I became unintelligible again, but for different reasons than hesitance; this was just as amusing to them.)
Coding is the same. Writing a small script, a prototype, or a little program for fun (or on the peak of the "Ballmer curve"), you don't think so much about structure and cleanliness, and you write the minimal amount that gets the job done, even if it's a hairy mess, and leave the editing pass for later (if ever). It's essentially the main tenet of Worse is Better camp and the Agile methodology: make it work as soon as you can.
I've worked at startups and large companies, and at both types of place, I've seen huge codebases, properly engineered and sometimes representing decades of man-hours, get scrapped before launch because they were wrong. I've also seen horrible code that ignored every good idea about building software that survived years. Personally, I have a bunch of code that is embarassing to look at, written as quick hacks, that has survived and done its job for years because it didn't try to understand the problem, just solve it.
Not that structure is bad or that engineering is wrong, but it seems to be independent of a program's survivability and its utility. In fact, Worse is Better seems to produce code that is more adaptable because its structure ignores edge cases that may turn out unimportant in the real world, so when unanticipated but important edge cases come up, the code is less rigid and can be adapted.
I think this lack of second guesses and of worrying about what doesn't matter for the problem at hand is exactly what the author is talking about. In terms of long-term maintenance, a prototype is cheap to build and easy to scrap; if it doesn't get scrapped and replaced, well...there will always be a project that junior programmers can cut their teeth on before subjecting a clean codebase to a kid fresh out of school.
Of course, not everyone is willing to pay for #2. "It's already done, isn't it?"
:(
In a more stable environment, dirty code will almost certainly come back to haunt you, or your successor. It's not worth 1 man-year to clean up 1 man-year of work, just so you could your job done a little faster. Besider, the pointy-haired manager will push you to speed up, even if it causes more problems later.
Even a start-up, though, has tons of code that is not part of the main codebase. A pile of monitoring scripts, a program that generates an arbitrarily large amount of data for a test database, the company's blog, internal mailing list software, etc. When you have fewer than 50 employees, it is okay if half of those codebases are ugly hacks.
Layperson who's never seen it: "Impossible"
Practitioner who's becoming better: "Extremely difficult"
Expert: "We do this all the time. What's the big deal?"
I think the only way to pull it off is to simply not care about the latter. Write comically straightforward code, as if you just learned to program, and go out of your way avoid wearing any kind of software engineering hat--unless what you really want to be is a software engineer, and not the designer of an experience.
I know that OP meant well, but I think this is about the worst advice I've ever seen here. A little background...
I have reviewed or maintained the code of thousands of other programmers, and I've encountered maybe a couple dozen I'd actually hire and about 5 I'd consider as technical co-founders. What's the biggest difference? Until today, I wasn't sure how to verbalize, but now, I think a good description would be those who appear to take OP's advice and those who know better...
AFAIC, there's is a close correlation between good code and user experience. There's a close correlation between readable code and maintainable code. There's a close correlation between expertise and precision to detail throughout. And perhaps most of all, there's a close correlation between something built properly to stand the test of time and long term user satisfaction.
If you want to learn a hobby, develop a passion, or really dig deep, by all means, follow OP's advice and just code it. Sometimes that's simply the best way to understand what goes on under the hood and learn what's possible once you learn the right way to build things. Once you learn the right way to build things.
But, please, please, please, leave your experiments on your own hard disk where they belong. You may have thought that those bleeding pixels were cool, but your name will be cursed by the poor souls who forever have to maintain your mess.
Also, some programmers don't take satisfaction in writing good code, this article will encourage them to stay in their bad ways, so that's not good. I think this article is good for people who take too much satisfaction in writing good code. Good code is not always an end in itself.
Right. It seems to me that most coding "best practices" are designed to help you maintain and build on your code. The guy who hacked together the animations would be in a world of hurt if his boss came in and said "we need the pool of blood to empty in case A, and in case B, it needs to be water, and in case C, it needs to be a cuddly bunny instead of a skull. Also the animation speed should vary depending on the time of day." This would be even worse if 6 months had passed since the original code was written.
Suddenly, refactoring for flexibility and clarity would sound really, really smart.
Now, if I'm writing a piece of "throwaway" code - say, a script that I'm going to run once to accomplish something, then never use again - I'd agree with "do what works and don't worry how the code looks." But generally, if your code matters to anyone at all, it will need to be tweaked and maintained.
The ability to rapidly prototype ideas is extremely valuable. For many early stage founders, a proof of concept is more valuable than a well engineered core product. The PoC gets them the funding, or the first customers.
For most people who have an idea, the PoC should come first, as suggested by the OP. I will agree that there are very few people that can write a PoC with production worthy code. They are real superstars.
Many engineers will knock together PoC before starting to write the main product. When I start out doing that, it's disposable. You throw it away.
Thanks for this guys. I really need to do a PoC so I can recruit some buddies to my idea.
There is obviously something to RAD, 4GL, etc. in terms of investigating the problem domain. Sometimes, you have to "just do it" to get clued up.
But I disagree with the implication that one ever reaches an expert stage where one easily balances the conflicting demands of real world program creation.
I don't think I'm original in claim that programming is inherently hard, even compared to other "difficult" tasks. It's hard because a client would prefer you "take on technical debt" (take short-cuts), it's hard because computer programs are among the largest artifact constructed by humans, it's because of the halting problem and any number of factors.
It's hard.
I just had to get that off my chest, OK?
That's fine as long as it generated jobs.
Yes, we developers sometimes focus on making the code perfect, beyond the point where there's an actual business case. So we need to be reminded that the code serves the business, not vice versa.
But really. Bad enough code is a liability to the business. You can't add features to make the customers happy, you get bugs you don't understand, it runs really slowly, etc.
The real trick is determining, with an intelligent conversation between developers and business people, what's good enough.
IT is expensive says Management.
So they offshore.
Job is gone.
Once industry sang the same song, we're done. No more IT practitioners in the US.
The shift is happening right now and it happens in a similar fashion: nobody feels it yet but suddenly the rug under them is gone one day.
Silicon Valley is an exception. There are always great companies like Apple and Google. And there are those poor startups that try to overwork the so-called "energetic, genius, creative" fresh-grads.
But the turn-over/turn-around rate is very high.
Stick long enough in this industry and we'll start seeing patterns.
The author is saying that getting something out is better than having a beautiful, difficult, half-completed and abandoned lump. It's really the same admonition as the ones to build the minimum viable product, or not to worry about premature optimization. Don't do work that isn't necessary! Every bit of unnecessary work increases the chance of total failure.
In the early stages, your biggest obstacle is getting SOMETHING, ANYTHING, out and working. We tell writers: sit down and write. We should tell programmers: sit down and program. Well, stand, if you don't want your back to ache.
I found myself in the same position as the author. As I was going through a CS program, I thought back to my early years of writing code. Sure, those early programs didn't have computationally optimal algorithms or the current {design pattern|algorithm|language} of the week, but they were fun, and I got stuff done.
Once I graduated, and now that I've been coding professionally for nearly 8 years, I find that the best way to keep that passion about code and not get encumbered by "how it's supposed to be done" is to read other peoples' code and work with really smart people who encourage you to be a better developer.
I guess the trick is combining some aspects of those approaches. I find it hard to do: it's now so obvious to me when I'm writing ugly and unmaintainable code that's Not Doing It Right that it's almost painful to make myself do it anyway.
Where code like the skull dripping blood or the exotic plants website breaks down is when you try to extend the codebase, scale it or handle more users. It's going to fall flat on its face and you're likely going to have to start over or refactor large portions of the code. That does happen sometimes, but at that point you probably understand your problem domain enough to know what the right features are and rewrite it anyways. So it's not always a bad thing. But when you do the rewrite, you should hire the people who know what they're doing and can write "concise, fast, scalable and maintainable" code.
This is not a strict dichotomy, of course. But it's a dictum well worth remembering.
My first pass is really about proving out the idea, learning about the domain, and finding any gotchas. The second pass is about using my experience from the first pass to create a clean, maintainable base.. something that I can come back to in a month and be able to maintain, enhance, and deploy without having to relearn everything again.
The point was not to write better code or to write code fast, it was that a 'good' programmer is focused on writing better code, not on what the user ends up seeing/experiencing (which at the end of the day is the important part). In the author's case, he focused on the wrong thing and ended up with a comparatively boring looking animation, despite having superior code.
Example: while working on a client's app, I spent two hours cobbling together a jQuery plugin to vertically align some dynamic navigation (sometimes the labels were one line, other times two or three). The project manager walked up and in five seconds said: "I made a website a while ago, I think you can vertically align table cells." Three minutes later, the nested table worked perfectly.
OTOH, it seems like something is clearly wrong here since, we are having a tough time being professional and working with the current crop of languages, tools, technologies, etc and in the same time, fully expressing our vision while enjoining our work.
Most beginning programmers will see few, if any, bears on the road ahead of them. That makes it easier for them to just move to the goal line.
Of course, good expert programmers will be able to see which bears actually are on the road, and plan for evading them, and not any other bears.
But on the other hand, if you consider it as a project triangle approach, you're given "Well-designed UI, maintainable code, cheap: pick two"
And as professionals, we want to express our clients' vision as much as possible, so we have to make a balance between having good code and the budget that the client gave us. It's not really the fault of our tools and technologies, but we do try to continually improve those tools so that we can provide the best service.
It's like having a song idea and learning to play an instrument so you can make it real.
This is a good analogy, perhaps better than the author realises. The way we learn to program tends to be nothing like the way music is taught, but it would be more effective if it were.Just as it's important to be able to nail scales through repetition, it's valuable to be able to type effortlessly, and to enter in patterns without thinking. Think of programmers who - when confronted by a linked list scenario - mindlessly hammer in what's needed.
Repetitive drilling of those patterns is a good mechanism for improving programming skill. Yet we tend not to think about learning programming this way. Think of that time recently where you struggled to get something working, and now when you need the pattern you just copy-and-paste from there. How many of us can reliably hammer out a socket server interface without it causing any cognitive load?
Unlike playing an instrument, programming is not dependend on muscle-memory skills to produce adequate performances, hence repetition is of limited use while studying.
I doubt I'll ever be a great programmer, but that's not really my goal anyway. I only hope to build something that needs to be rebuilt due to scaling problems. :)
Just build your vision - especially when you're stretching with unfamiliar tools and languages.
Then go back and pay off your technical debt.
Architecture is why we refactor
I sincerely disagree with this point of view. To me, 'architecture' consist of exactly all those aspects of an application that you can not change by a mere refactoring. There are parts of an application's design that are much harder to change, after the fact, than others.If you've built your Japanese pagoda from wood and rice-paper and you decide afterwards you're really going to need a concrete foundation and some central steel columns to tie your pagoda to it, you're basically going to have to rebuild it.
However, now that I am building my own app, I have forced myself to learn the entire stack (from Rails to JS and beyond).
I sometimes look at other people's code and compare what they did in 1 line, to what I did in a block of 10 lines and wonder when I will be able to write elegant code like that. But I have learned to console myself, that at the end of the day, for this first release, it doesn't matter what the code looks like. Just so long as it isn't slow and the user has a good experience (i.e. things behave the way they expect it to), then I am doing a good job.
The perfectionist in me hates leaving it like that (I want to refactor every chunk until it is completely optimized), but the realist in me knows that I only have X amount of time to complete.
Thanks for posting this, because now I don't feel like I am doing a major disservice to my users by programming like the n00b I am.
Often naive algorithms and shortcut solutions work great. But make them so that when you actually need to replace them you just unplug them and replace with something better.
˚and by program, I guess I just mean building stuff.
Merry Christmas!