Make it work first, then make it better

Sometimes, worse is better. As strange as it may look, having something that is not perfect may be better than spending the time to make it perfect. This happens in many areas, and its the main reason perfectionists never get any work done. If the expectation is for perfection, then it is really hard to complete anything, because most of what we do is imperfect by necessity.

In software, however, there is an extra dimension to this problem. Because, the closer to perfection we get in a software application (in terms of features) the more code needs to be written and maintained. More code also means more bugs, which have the power to move us even further away from perfection.

Given the complexity of writing perfect software, it is just better to admit that we can’t write perfect programs. Instead, a more attainable goal is to write the minimum necessary to satisfy our requirements, while maintaining a good control of the overall design.

Writing as few code as possible has several advantages that contribute to the quality of the resulting programs:

It is easier to test: every extra line of code is a new place where errors may be hiding. Why increasing that chance? Just write as few lines as you can and avoid potential problems.

Avoid unnecessary repetitions: a guiding principle of programming is the DRY method: Don’t Repeat Yourself. While trying to write as few code as possible you will see more opportunities to avoid unnecessary repetitions.

Performance: usually, less code leads to better performance. This is particularly true for modern software, where one of the main limitations is processor cache size (as opposed to main memory size). Small programs that solve the problem without requiring huge class libraries may have a big advantage in the performance arena.

It is not always easy to write small programs though. Remember the old saying: “I wrote a large book because I didn’t have the time to make it small”… The same apply to programs. It is sometimes easier to copy and paste previous code, or code that was mindlessly taken from some other project or from the web. It is harder to think about the overall problem and adapt the code to your situation.

What about making it fast? Well, it turns out that making programs fast is more a matter of design than of good programming skills. It is futile to change a program to yield better performance if the structure of the program is not created with this in mind. And once you get the big picture of the software design, getting small improvements in speed is not that interesting. There are exceptions to this rule; for example, video games can use small speed gains to give much improved user experience.

So, you see that writing small programs has a lot of virtues. And, despite this, it is a difficult task, because it requires a lot of thinking in advance. Developers are most of the time pressed to think less and finish more lines of code. But it pays the time to look for good solutions before you enter code into your preferred IDE.

  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • E-mail this story to a friend!
  • HackerNews
  • Reddit
  • StumbleUpon
  • Twitter

Using the sam Editor

The sam editor is a text editor written by some of the same people that created UNIX, including Ken Thompson and Bob Pike. Many of them worked previously on the AT&T Labs (the lab has mostly been disbanded, but many of these guys still work for other companies).

The sam editor provides many of the same features found on a previous editor, called ed (also known as the standard UNIX editor).

If you know enough about UNIX to understand what ed is, you may be asking me: why are people still bothering with concepts related to a line oriented editor? This is a program that was superseded decades ago by vi, wasn’t it? (In fact, I know that the Emacs crowd will additionally say that Emacs superseded vi, to which I reply that vim superseded Emacs…)

But the truth is, for old fashioned as ed may be, it still has some ideas that are interesting exploring. First, ed was born at a time when there was no easy way to interact with a screen of text. Therefore, it had to create a mini-language that allowed people to efficiently enter text without a mouse or other form or cursor.

For example, using ed one can easily say: go to the next line (in a C source file) that has a declaration of an integer, and add a new variable at the end of the line.

For the ones among you that never tried this, here are the commands:

/int
s/;/, newVar;/

Here is what this means: “/int ” will search for a line that has the “int” keyword on it (notice that I added a blank after “int”). Then, substitute the character “;” by the sequence “, newVar;”.

Effectively, the previous commands use search and replace to edit text.

If you use vi, you will notice that several of these commands have resemblance on existing vi commands. That is because vi was designed as a full screen version of ed. For example, the file access operations are still the same. Also, virtually all commands supported by ed can be accessed in the so-called “ex” mode (ex is usually just another name for ed).

For users experienced in ed, one advantage of using it is that there is no need to use anything other than the keyboard. Also, movements are done by search patterns or direct line references, which are typically much faster than using a mouse (or arrow keys, for that matter).

Of course, there is something missing in ed, which is the possibility of seeing the whole file. You can always use an external program, such as more (or less), but this is somewhat awkward.

The sam editor takes the concept of ed one step further, but in a different direction than vi. It also provides a graphical UI, but instead of relying on two modes of operations as vi, sam provides an improved set of commands to ed, along with a way of entering and viewing the results of these commands.

The result is an editor that is refreshingly different, while providing the same power of the commands available in vi and ed. For advanced users, sam may be an additional tool that can be used whenever the strong features of the editor are required.

Of course, sam is the main editor for plan9, so people using it are already used to the conciseness of sam. There is just a small set of commands, which can be learned in a few hours. The combination of these commands is what provides the flexibility of its approach.

The UI is divided into a number of windows. One of them is the command window, where editing commands are typed. The interesting thing is that the command buffer has all the features of a normal window, like autoindent, for example. Thus, adding and editing text through the command window is as comfortable as using any other editor window.

Although sam provides a lot of nice features, it is not as widely used as Vim or Emacs. Therefore, it has some rough spots, specially in the UI (the most GUI (the most difficult part to get right). The fact that it was developed for plan9, instead of UNIX, also brings some difficulties. However, despite these issues I

However, despite these issues, I have found sam to be very easy to learn and use. It has already become one of my favorite text editors.

Further Reading

Inferno Programming with Limbo is an introduction to the main operating system based on plan9. It will give you some idea of what the environment is, and why it is radically different from other OSs.

Learning the UNIX OS talks about several original UNIX commands, including ed.

  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • E-mail this story to a friend!
  • HackerNews
  • Reddit
  • StumbleUpon
  • Twitter

In Software, Good Design is Everything

Designing is one of the most important and overlooked areas of a programming project. After all, how important it is creating a UML diagram if it will not be used during the coding of the system? On the other hand, stop and think about the good software that you have used, such as vim or UNIX. What do they have in common? The unsurprising answer is: they have good design.

Designing software is not the same as creating nice UML diagrams. I know a lot of programs that have beautiful UML diagrams but are terribly bad designed. On the other hand, some of the most interesting architectures were not created from an UML diagram. From a pragmatic perspective, having a good design means that the resulting architecture provides the basic mechanisms for extending the original program without the need to rewrite its basic components.

In a well design program, developers can feel confident to extend the system, without thinking that they need to understand something very subtle about its internals. For example, very few people need to know how UNIX is internally implemented in order to write a new application. You also don’t need to know the internal architecture of Emacs to create a new package. These are examples where a system possess a strong technical foundation to which additional functionality can be easily added.

On the other hand, a badly designed piece of software can have growing costs that will continue forever as long as changes are necessary. If there is any need for extension in such a system, then one has to understand how each piece works together. Working in this way is like playing with a house of cards: for lack of a foundation, any change in the system can bring the whole thing down.

Moreover, even if no further extension is required, think about the costs of maintaining a low quality system like this. In general, what this means is removing bugs that will inevitably appear from time to time. In a badly designed software, high attention to detail is necessary to avoid a mess that may be eventually caused by the addition of a single instruction.

This kind of flakiness in software is what costs so much time and money on common projects. Many such projects start with the explicit (and misplaced) goal to create a program quickly. However, not spending the time on design may have bad consequences for the future of a project. If the basic architecture is not in place, it becomes increasingly difficult to make changes, and huge amounts of time are lost during the main parts of the project.

The lesson from these observations is that everything starts with good design. If your software doesn’t have a good design, it is doomed. Even though there is a huge pressure to create software quickly, the initial design is the most important part of the process. Skipping this step can hinder the whole effort and turn your project into another nightmare, that is sadly so common on software shops.

Further Reading

The mythical man-month is the classic book on design issues on software engineering. I highly recommend it for anyone interested in software design.

  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • E-mail this story to a friend!
  • HackerNews
  • Reddit
  • StumbleUpon
  • Twitter

How to Avoid the Second System Syndrome

The second system syndrome is a phenomenon that happens every time a person or company tries to rewrite a successful software for a revamped second version.

The syndrome is characterized by lots of promises (the next version will be the best ever…), long release cycles, and usually failure from the part of the developers to create something that is even close to the expected.

The same set of events have been observed throughout the industry in several occasions. A company that goes through this kind of cycle either has to go back to a previous version and stop development of the much awaited new incarnation of the product, or in the worst case becomes completely irrelevant.

Of course, this kind of syndrome doesn’t happen only in the second version of a software (the 2.0), it can happen in any stage of the lifetime of a software product. For example, Netscape rewrote their browser between the versions 3 and 4, and almost killed it. Microsoft tried to rewrite Windows several times in the last 20 years. With the only exception of the launching of Windows NT, which was a completely different product at the time, all planed rewrites took longer than expected and resulted in an inferior version being released.

From the experience accumulated by companies of all sizes, there are a few recommendations that can help avoiding many of the mistakes mentioned above.

Don’t try to make everything better at the same time: one of the reasons for defeat by the second system syndrome is having no clear goals. If you just setup to create a new version of your software that is better in any way, this is mostly a recipe for failure. There is an infinite number of improvements you can make to a program. You won’t have time to make them all work.

To avoid this danger, start by clearly defining an area of the system that will be improved in the next version. Maybe you can add a second area, but the more focused you are, the better your results will be.

Another helpful suggestion is to concentrate on specific features, not on the general feeling of the application. Features can be implemented, abstract ideas cannot.

Internal Changes

Another reason people feel the need to rewrite a program is the idea that its source code is ugly, and should be changed. While this may be a good reason for making internal improvements, it is rarely a reason for rewriting a program.

Remember, users don’t see your code. They are not attracted to your program because of the clarity of the source code. All they see is the implemented features of your application. While you have to strive to write maintainable, clean code, such an advantage is not worthy the price of a complete rewrite.

Conclusion: instead of being too ambitious and disappoint your users, it is much better to provide great new features in each version of your software. Avoid the second system syndrome: users will be happier and you, as a developer, will have a much better time.

  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • E-mail this story to a friend!
  • HackerNews
  • Reddit
  • StumbleUpon
  • Twitter

How to Decide if you Should Write a Program

As a developer, have you ever wondered if a program needs to be written? With the library of existing programs growing larger than ever, it is sometimes difficult to justify the need to write still another one. Especially when the need for a program may not be well understood in principle.
Like anyone that need to prioritize activities, I had to come up with a few guidelines to decide in which to spend time. Here are some of them:
Is anyone paying me to do this? Like it or not, this is the number one reason if you have to work for a company and you are not a decision maker. With luck, however, you can have a say on how the company will spend its efforts and the next reasons will apply. Also, you may be working on your own company or open source project.
Does it provide a feature that doesn’t yet exist? While it is tempting to write “yet another” program to do something that is well known, the benefits of doing this are small. This is a situation where you need to create something really better just not to be perceived as another copycat. While this might work if you have a lot of experience on the subject domain, why take an unnecessary risk? If I don’t have any really good idea to improve something, I just let it alone.
If the functionality exists, would it be much better than current options in some way like time, easy of use? This is the test you need to do whenever you are tempted to rewrite something. If you cannot convince yourself that it would be better for your users, don’t spend the time.
Rewrites of a program are dangerous. Keep in mind the second version syndrome, whereby developers try to improve the existing system in every conceivable way, just to learn that users don’t want it anymore. This is a particular case of trying to do too a perfect job: and you know, perfect jobs don’t exist.
Can you learn something from it? If I cannot convince myself that the program will be new or much better than the existing, then I ask if it will teach me something new. This is something that works particularly well for personal or open source projects: no wonder there are thousands of open source versions of every application. Most of them start as a vehicle for someone to learn about an application domain. Such projects frequently gain their own life and become something useful for others.
Has any commercial value? If you cannot learn anything new, it might still have commercial value. For example, it can complement a major product your company might have. This is the common case when a major product adds functionality that exists somewhere else, but that would still be useful to complement the original program. Be aware of the proliferation of features that can make your product harder to use and slower/buggier.
Is it fun to write? Some programs begin their life just as a way to have fun. Lots of developers have fun writing new compilers, editors, and similar system software. That’s why there are so many of them around. This is something that usually goes together with learning something new: developers having fun can be a very powerful force.
Will it help anyone? There are times when you don’t have any other reason to write a program other than helping someone to solve a problem (that someone can even be yourself). Sometimes you may be trying to help your wife, your brother, or your neighbor, with some functionality that would be easy to write yourself. My first suggestion is trying to find similar functionality somewhere else. But if you can’t, and it is easy, why not do it? This is one of the advantages of understanding how computers work, right?

  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • E-mail this story to a friend!
  • HackerNews
  • Reddit
  • StumbleUpon
  • Twitter