Rapid Development Skill

This topic is different from RapidApplicationDevelopment.

Some people seem to have the ability to very quickly write out programs to test ideas in hard languages like C++. Other people can rapidly develop experimental gui programs in languages like Scheme (MIT is packed with people who rapidly develop interesting prototypes in Scheme like languages).

I on the other hand am nowhere near as effective at being able to write programs to test new ideas. And it isn't from lack of practice. I spend large volumes of time programming.

So, are there tricks that I'm missing here? Working in languages other than C++ seem to be a good starting point. Also, languages other than VB also seem to be a good idea. Is there some sorta lisp framework that I'm missing out on (at MIT, they have dozens of lisp frameworks, like Isis).

Maybe things will go better as I get better with Squeak.


I had a hypothesis about this. When a programmer writes code, that programmer has to make innumerable decisions. These decisions often have far-reaching consequences, and yet the programmer has to make them every five lines of code or so.

Therefore, you will program faster if you make decisions faster.

Sometimes experience makes it possible to make decisions faster, but sometimes the opposite happens: you learn about more and more options that you have to choose from among. Some languages make some decisions unnecessary - there's only one way to do it, or all the ways are equivalent anyway - so you don't have to choose, or you don't have to care. Other languages, such as C++, give you a lot of choices with far-reaching consequences. Sometimes tight deadlines make it uneconomical to spend time finding and weighing options, and you have to take the first possibility that comes to mind. Sometimes programmers develop the belief that their choice doesn't matter much anyway - they are confident in their ability to deal with their own code. Other people (like me, and like DonaldKnuth) enjoy finding all the options and weighing them carefully. They probably write better code, but it takes them much, much longer. Some people (again, like me) have trouble weighing the options because they have to speculate about how the code is going to be used in order to decide.

(I don't mean to suggest I'm anywhere near as good a programmer as Knuth is, by the way...)

Once when I was a student on a tight deadline, I wrote a non-deterministic PDA simulator in Java in just under twelve hours. It was 800 lines long and only had one or two non-serious bugs (which were found and fixed later, after I turned it in). It worked. I felt burned out for days after that, but I was proud. It proves I can be a fast, decisive coder - but I'm usually not.

In the time I spend deciding, I could be coding. I try to tell myself, "Just pick one!" Maybe someday that'll become my habit. -- EdwardKiser

To speed your coding, do less optimisation. Use a loop that goes over the entire array from start to finish, rather than using some kind of boolean divide and conquer. Don't refactor equations into simpler forms, even if it means you end up multiplying something by x/x. Write equations in their original form, with whatever transformations you need just tacked on. To calculate a Fahrenheit temperature which is 32 degrees lower, given a Celcius input, just write "9/5*C+32-32". Especially do this if you are fooling about with strings and substrings ... I'll often have some calculation that looks like mid(string,x+2+1+1,y-1-1) ... because I'm thinking "x is the offset, plus 2 for the prefix, plus 1 for the delimiter, plus 1 for the leading space".

(These examples are deliberately simple to illustrate the point.)

Don't optimise, don't even take the time to examine what you just wrote to see if optimisation is even possible. If it works, move on to the next statement. -- EricScheid

I don't usually optimize, if by "optimization" you mean trying to choose the way of saying something that will work fastest on the machine.

But I do optimize, in the sense that I try to write code that will be easy for me to verify the correctness of, understand, and change, later. Deciding how to do that best can be hard, because you can't predict your own future needs, and there are always trade-offs.


There is more to this than just making decisions quickly and deferring optimization.

Turnaround time on an edit-compile-test cycle is essential. If you can write code for a minute and see how well it works in a matter of seconds after that, you won't be as attached to any set of changes. This also helps in making decisions quickly, since you can reverse many wrong ones within 5-10 minutes. This is SmallIncrements? [okay, it isn't, but I forget which page describes what I mean. feel free to fix it if you figure it out]. If you can't do this, you can't really explore a problem, since it just takes too long to get feedback.

The ability to pound out code that obviously won't work beyond the simplest case you can imagine, and then making sure that it does work for that simplest case before going back and fixing it to be more general. Yes, this is the SimplestThing doctrine again, and ReFactoring.

The ability to defer fixing the code for the simplest case indefinitely, usually putting a FIXME comment in as a marker.

Adhering to some sort of CodingStandard. It doesn't have to be complex or formal (and is probably better off being neither), but it really helps when it comes to maintaining things later. (Not only that, but it keeps you from having to make a lot of trivial decisions.)

If you are just pounding out a one-shot utility, take the time to document all the major open issues at the top of the file (or in a separate TODO file) when you're done. Odds are if you needed a utility once you'll need it again, and when the time comes to improve it or use it elsewhere you will want to clean it up, and that means knowing where it's broken. Time spent on this now saves more time later.

Use a good editor, preferably one with some level of integration with your build tools. Emacs and VisualStudio both count here. Hitting the build button, and being able to hotkey immediately to each compile error in turn is very convenient. There are many other simple things that a good editor can do to help speed up development.

Know your programming language. There are times when &"Win\0Lose"[(!result) << 2] is the right thing to do in C. Learn how to recognize those times (there's another example of this in BracesAroundBlocks, look for the word "IOCCC").

Know your libraries. There's no sense in writing a sort routine in C when you can use qsort(). When working in C or C++, feel free to abuse the preprocessor (I have several projects that have macros that take three or more arguments, and spit out a function).

Advanced tricks:

Think, and apply the results of your thought. Just Thinking isn't enough, you have to Do.

If there's some tool or change in your environment that you think will make it easier or faster for you to write code, try it. Write the tool, if necessary.

After you've written essentially the same function for a third time, or even a second, add it to your personal library of reusable code.

Don't write out a new makefile for every project, have a template makefile that you can copy in, and have it .include all the common rules and definitions. Have it automatically maintain dependency information for you (manually updating dependencies sucks).

Have template source files for common kinds of programs that you make. If you frequently make programs that take a filename on the command line, read the entire thing into memory, do something on the data, and quit, then have a template for it. Even better, put the common code in a header file somewhere, and #include it in your programs (yes, I do have some programs that define a function called do_something(), and then #include a file that defines main for them).


The biggest problem is making changes. Making changes is much more complex than simply adding on to the end of an unfinished program. Why? Because a program is a directed graph: functions and classes depend on other functions and classes, and if you let each function or class be a node and you let dependency be a directed edge, you end up with a directed graph.

Adding on to the end of a program is easy: you just add a new node, which depends only on existing nodes. Nothing depends on the new node yet when you add it. You test the node, it works, you repeat the process.

Changing a program is hard because then you're picking a node out of the middle of the structure and hoping to change it without disturbing the nodes that depend on it. Because if you remove a node, you break all the nodes that depend on it. Change a node and the changes might reverberate throughout the code.

(This is one of the reasons why it is useful to have tools which will parse your code and find every place that a given function or variable is called or used.)

It's possible to make some future changes easier, but it requires you to think about the nodes that don't exist yet, that are going to depend on the node you're writing now. And you have to think about what kinds of changes you might like to make, and whether there's any way you can prepare for those changes without wasting too much effort.

Part of the appeal of object-oriented design and programming is that it is supposed to make this possible by separating interface from implementation.

However, it's amazing sometimes how a change to the implementation might require an interface to also be changed.

ReFactoring is the only long-term solution. You can't predict the future, so don't. Make changes in small steps.


See also: ReFactoring, OptimizeLater


EditText of this page (last edited May 21, 2006) or FindPage with title or text search