Make It Work Make It Right Make It Fast

This formulation of this statement has been attributed to KentBeck; it has existed as part of the UnixWay for a long time.

See ButlerLampson's "Hints for Computer System Design" (1983) http://research.microsoft.com/en-us/um/people/blampson/33-hints/webpage.html

The second half of this (making it right before making it fast) is really just a reformulation of the RulesOfOptimization.
I just fixed the broken link to Butler Lampson's paper. -- RickDeNatale
If it doesn't work right, in what sense does it work at all?

Here's my interpretation. First crank out code that handles one common case (MakeItWork). Then fix all of the special cases, error handling, etc. so all tests pass (MakeItRight?).

Another interpretation, "Make it right" means make the code more clear, i.e., refactor. "Make it work" is the part about getting the code to operate correctly. A rephrase might be, "Make it work correctly, make the source code clear, make it run quickly."
This reminds me of something KentBeck wrote in TestDrivenDevelopment: Write a test, make it run, make it right. To make it run, one is allowed to violate principles of good design. Making it right means to refactor it. -- DaveHoover

Isn't this a violation of the law of IncompatibleGoals - "Good, fast, cheap - pick any two"?

No. There is no "make it cheap" in the phrase.

Quite correct. However, there is "make it right" followed by "make it fast". Does fast mean "run quickly", or does it mean "do it right now", in which case they are incompatible goals?

I don't think it means either 'make it quickly' or 'make it right now'. I think it means 'Make it become fast'. I have always taken it as a statement of evolution of one's solution. I.e., to mean "make the code work, then make it 'right' (as in morally correct, i.e. good design), then make it run quickly". Is this the canonical interpretation? -- PaulMitchellGears

What happens when 'right' also means 'fast'? Localized optimization certainly is the root of all programming evil. But is global optimization?

[Note: Global optimization is making design choices that become very difficult to change after you've made such decisions because they pervade your code base.]

Right. "Make it work, make it right, make it fast" is an assertion that if you can "make it right", you'll be able to "make it fast" later. You won't need to do any global optimization - it'll all be local. It's only those times when you can't "make it right" that you have to DesignForPerformance ahead of time.

"Right" never means "fast", though "fast" may be an equally important requirement. If so, you first make it "right" (and possibly slow), then transform the "right" program into the "right and fast" program. While doing so, you always have a way to check whether the program is still "right", at the very least by comparing it against the known "right and slow" version.

Should you attempt to directly write the "right and fast" version, you'll get tangled up in complicated algorithms and non-obvious structures and it will never become "right" because you don't understand your own code any more. After all, if it isn't "right", it doesn't matter much how quickly it delivers the wrong results.



My interpretation of this phrase is that it describes the relationship between TestFirstDesign, DoTheSimplestThingThatCouldPossiblyWork, and Refactoring.

When I first started TestFirstDesign, I found I was spending way too much time thinking about good names, good structure, etc. What I found was that it was far more productive to do just the bare minimum to get the test to pass. If one can think of a good method or variable name, use it, but if not, just use the first thing that comes to mind. If one does not want to type in a long descriptive variable name, use a short one instead. Just pass the test, just make it work. Now that the code works, improve method and variable names; do a search and replace to change short names to long descriptive ones; move methods to different classes, subdivide methods, combine methods, reuse existing methods. Now is the time to make the code structurally and aesthetically please, make it right. Finally, the performance of the program as a whole is important. Make sure the new operation runs adequately fast and does not excessively degrade other operations. If need be, make some alterations to improve the performance, but only if it is necessary or at least desirable. Now is the time to make it fast, but only address speed where it is needed.

I think software, at the micro-level, challenges the common belief, "If you can't do it right the first time, when will you have time to do it over?" Experimentation is needed to determine what is "right" whether one does the experimentation in one's mind or by trying different versions of the code. It usually takes longer to get that mental model right and only have to type the code in once, then to try a version of the code and do it over as needed. -- WayneMack
I've heard a different version of this phrase: MakeItWorkMakeItSmallMakeItFast.
Often making it fast is making it right. If you don't think about your design then you are unlikely to meet your requirements. Handling interrupts, for example. Frame rates for video playback. Quality of service guarantees. Task latencies.

Concur. (This is obviously EmbeddedSystem weenie talk, but you strictly application mushheads can listen in and learn something.) Refactoring to the smallest kernel of operations means that your interrupt handlers don't make any decisions, your data is moved through the minimum of layers, and everything progresses as quickly as the code can be made to work. That's fast. That's right. But only if it all works.

EditText of this page (last edited February 18, 2009)
FindPage by searching (or browse LikePages or take a VisualTour)