Code Simplicity

Essays

Specific Solutions

Posted by Max Kanat-Alexander
On April 22nd, 2008 at 06:04

Permalink | Trackback | Links In

Category: Essays

So, I’m a huge Kyle XY fan, and I was entertaining myself this morning by watching the various “behind the scenes” clips that they have on the website. Of course, before each clip was an ad–the same ad every time–for The Sims. No matter how silly the ad may be, being forced to watch it over and over did eventually get me thinking–although not about buying The Sims:

Why has The Sims sold 100 million copies, while Second Life, an ostensibly much more flexible and powerful universe, only has about 2 million active users? They look pretty similar, and you might guess at first glance that they’d have somewhat similar audiences. But, although 2 million users is nothing to scoff at, 100 million absolutely trounces it. So why the big difference?

Well, of course, The Sims has EA Games behind them, who have a massive distribution channel and a lot of marketing power, but the Internet buzz and general promotion of Second Life is pretty good too, so although EA has the edge, that doesn’t explain a 50-to-1 difference in sales. There must be something actually different about the products themselves.

Well, at first glance, The Sims is very user-friendly and Second Life is (from what I’ve heard) hard to use. The Sims does a limited scope of things very well, and Second Life does an unlimited number of things through a difficult interface, with mediocre results.

But fundamentally, why is it that products like The Sims succeed so much more than things like Second Life? And why does The Sims have a better interface, why do people want to play The Sims more than they want to play Second Life? (Read More…)

Instant Gratification = Instant Failure

Posted by Max Kanat-Alexander
On April 9th, 2008 at 12:04

Permalink | Trackback | Links In

Category: Essays

The broadest problem that I see in the software industry is that companies are unwilling to engage in strategies that only show results in the long term. Or, more specifically, that organizations are unaware that there is any such thing as a long-term strategy.

In the US, it’s probably a symptom of a general cultural problem–if an American can’t see an instant result from something, they think it doesn’t work. This leads to fast food, french fries, and fat people. The healthy way to eat (protein and vegetables) has a delayed effect on the body (you don’t get the energy for over an hour), and the bad way to eat (endless carbohydrates without nutritional value) has an instant result–immediate energy.

Software is always a long-term process. I wrote the first version of VCI in about three weeks, and that was insanely fast. Any actual application (VCI’s just a library) takes months or years of person-hours, even if you keep it small. So you’d think that organizations would be far-sighted about their development strategies, right?

Unfortunately, it just doesn’t happen. Competitor X comes out with “Shiny New Feature” and The Company says “we must have Shiny New Feature RIGHT NOW!” That’s not a long-term winning strategy, that’s just short-sighted panic. If you have users, they’re not all going to get up and go away in the next five minutes just because somebody else has one feature that you don’t. You should be looking at trends of how many users you’re gaining or losing, not just responding mindlessly to the immediate environment.

So what’s a good long-term strategy? Well, refactoring your code so that you will still be able to add features in the future, that’s a good one. Or spending some extra time putting some polish on your features and UI so that when the product is released, users are actually happy with it. Not adding features that you don’t want to maintain, if they’re not important enough–that’s another one.

Remember that Mozilla did poorly for years, only to finally start gaining dominance in a market that Netscape had lost, because they had a long-term plan. Granted, Mozilla made some decisions early on that caused some things to take longer than they should have, but they still won out in the long term, despite failing in the short term.

Of course, it can be hard to convince people that your long-term plan is right, sometimes, because it takes so long to show results! When I started refactoring Bugzilla about four years ago, there was pretty constant resistance, particularly when I would review patches and say, “You need to wait for the new architecture before this can go in,” or “This needs to be fixed to not be spaghetti code.” But once the refactoring really got rolling (after about two and a half years), it suddenly became way easier to add new features and nearly all the developers became big supporters of refactoring.

I read so much “advice” on “how to run your software business” that just focuses on instant gratification–what you can get done right now. “Add features!” “Get millions of dollars instantly from VCs!” Unfortunately, the way the universe seems to work is that you can destroy something in an instant, but it takes time to create something. So in reality, the closer you get to “instant gratification”, the closer you get to destruction of your product, your business, and your future.

If you want a good plan, pick one that admits that creation takes time. It doesn’t have to take forever, but it’s never instant.

-Max

There Is No Science Of Software

Posted by Max Kanat-Alexander
On February 19th, 2008 at 15:02

Permalink | Trackback | Links In

Category: Essays, Laws of Software

What we think of today as being “computers” started out in the minds of mathematicians as purely abstract devices–thoughts about how to solve math problems using machines instead of the mind.

These mathematicians are the people we would consider the modern founders of “computer science.” Computer Science is actually the mathematical study of information processing. It is not, as some people believe it to be, the study of computer programming. In fact, there is no science of computer programming. To understand how that could possibly be true, and what I mean, you have to know the history of programming.

The earliest computers were built under the supervision of computer scientists by highly skilled electronic engineers. (Read More…)

Simplicity and Strictness

Posted by Max Kanat-Alexander
On February 13th, 2008 at 13:02

Permalink | Trackback | Links In

Category: Essays

As a general rule, the stricter your application is, the simpler it is to write.

For example, imagine a program that accepts only the numbers 1 and 2 as input and rejects everything else. Even a tiny variation in the input, like adding a space before or after “1″ would cause the program to throw an error. That would be very “strict” and extremely simple to write. All you’d have to do is check, “Did they enter exactly 1 or exactly 2? If not, throw an error.”

In most situations, though, such a program would be so strict as to be impractical. If the user doesn’t know the exact format you expect your input in, or if they accidentally hit the spacebar or some other key when entering a number, the program will frustrate the user by not “doing what they mean.”

That’s a case where there is a trade-off between simplicity (strictness) and usability. Not all cases of strictness have that trade-off, but many do. If I allow the user to type in 1, One, or " 1" as input, that allows for a lot more user mistakes and makes life easier for them, but also adds code and complexity to my program. Less-strict programs often take more code than strict ones, which is really directly where the complexity comes from.

(By the way, if you’re writing frameworks or languages for programmers, one of the best things you can do is make this type of “non-strictness” as simple as possible, to eliminate the trade-off between usability and complexity, and let them have the best of both worlds.)

Of course, on the other side of things, if I allowed the user to type in O1n1e1 and still have that be accepted as “1″, that would just add needless complexity to my code. We have to be more strict than that.

Strictness is mostly about what input you allow, like the examples above. I suppose in some applications (like, say, a SOAP library), you could have output strictness, too–output that always conforms to a particular, exact standard. But usually, it’s about what input you accept and what input causes an error.

Probably the best-known strictness disaster is HTML. (Read More…)

When Is Backwards-Compatibility Not Worth It?

Posted by Max Kanat-Alexander
On February 11th, 2008 at 18:02

Permalink | Trackback | Links In

Category: Essays

This title might seem a bit like a contradiction to my last post! Well, you really shouldn’t break your API, if you can help it. But sometimes, maintaining backwards compatibility for any area of your application can lead to a point of diminishing returns. This applies to everything about a program, not just its API.

A great example of the backwards-compatibility problem is Perl. If you read the perl5-porters summaries with any regularity, or if you’re familiar with the history of the Perl internals in general, you’ll have some idea of what I mean.

Perl is full of support for strange syntaxes that really, nobody should be using anymore. For example, in Perl, you’re supposed to call methods on an object like $object->method(). But there’s also a syntax called the “indirect object syntax” where you can do method $object. Not method($object)–only the case without the parenthesis is the indirect object syntax.

Really, nobody should be using that syntax, and it’s not that hard to fix applications to call their methods the right way. And yet that syntax is maintained and supported in the Perl binary to keep backwards compatibility.

Perl is full of things like this that block forward progress because of historical problems.

Now obviously, this is a balancing act. (Read More…)

What Is Overengineering?

Posted by Max Kanat-Alexander
On January 29th, 2008 at 23:01

Permalink | Trackback | Links In

Category: Essays

Software developers throw around this word, “overengineering,” quite a bit. “That code was overengineered.” “This is an overengineered solution.” Strangely enough, though, it’s hard to find an actual definition for the word online! People are always giving examples of overengineered code, but rarely do they say what the word actually means.

The dictionary just defines it as a combination of “over” (meaning “too much”) and “engineer” (meaning “design and build”). So per the dictionary, it would mean that you designed or built too much.

Wait, designed or built too much? What’s “too much”? And isn’t design a good thing?

Well, yeah, most projects could use more design. They suffer from underengineering. But once in a while, somebody really gets into it and just designs too much. Basically, this is like when somebody builds an orbital laser to destroy an anthill. An orbital laser is really cool, but it (a) costs too much (b) takes too much time and (c) is a maintenance nightmare. I mean, somebody’s going to have to go up there and fix it when it breaks.

The tricky part is–how do you know when you’re overengineering? What’s the line between good design and too much design?

Well, my criteria is this: When your design actually makes things more complex instead of simplifying things, you’re overengineering. (Read More…)

How Simple Do You Have To Be?

Posted by Max Kanat-Alexander
On January 25th, 2008 at 20:01

Permalink | Trackback | Links In

Category: Essays

Sometimes, when you’re working on a project, there’s a question of, “How simple do we really have to be?” “How much do we have to simplify this thing?” “Is it simple enough?”

Well, of course, simplicity is relative. But even so, you can still be more or less simple. From the relative viewpoint of your user, your product can be hard to use, easy to use, or somewhere in between.

So, how simple do you have to be?

Honestly?

If you really want to succeed? (Read More…)

Complexity Is a Prison

Posted by Max Kanat-Alexander
On January 22nd, 2008 at 22:01

Permalink | Trackback | Links In

Category: Essays

Sometimes, I think, people are worried that if they make their code too simple, then either:

  • Somehow they’re not demonstrating how intelligent they are, or how valuable they are, to their managers, or
  • The project will become so simple to work on that anybody can just steal their job!

It’s almost as though if they actually did their job right, then they’d lose it. Now, stated that way, that’s obviously a nonsensical viewpoint. But, if you’ve ever worried about it, here’s something to think about:

What if your code is so complex that you’ll never be able to leave your job? (Read More…)

Purpose and Simplicity

Posted by Max Kanat-Alexander
On January 18th, 2008 at 14:01

Permalink | Trackback | Links In

Category: Essays

A fast way to get complicated is to violate the purpose of what you’re doing.

For example, what’s the purpose of a web page? To give and receive information. Mostly to give information, and then some websites also take information, such as when you’re buying something.

How many complicated web pages have you seen that think they’re doing something else than giving or receiving information? Maybe they think they’re being entertaining, or something. I don’t know what their designers were thinking, but they probably weren’t thinking about giving or receiving information. Instead they’re hiding their information in a complicated mass of pictures and shapes.

Usually, the basic purpose of any given thing you’re working on is pretty simple. But if you add to that purpose, things can get complex pretty fast! For example, the basic purpose of Bugzilla is to store and organize bug reports. If we suddenly made Bugzilla also able to read your email, it would get ridiculously complicated. (Not that Bugzilla is the simplest program in the world, but we’re working on it.) Can you imagine what the UI would look like? Where would we put all the buttons? That would be a violation of Bugzilla’s purpose.

It’s also important to think about user’s purpose. (Read More…)

Simplicity Is Relative

Posted by Max Kanat-Alexander
On January 16th, 2008 at 21:01

Permalink | Trackback | Links In

Category: Essays

Defining “simple” really depends on your target audience. What is simple to me might not be simple to my mother, or my friends. Also, when I create something, it’s always relatively “simple” to me, because I understand it inside and out. But to somebody who’s never seen it before, it might be very complicated.

This is why in VCI I put a big, obvious section of documentation near the top called “New To VCI?” And then it contains some simple, obvious steps to take. It’s written as if the reader knows nothing about VCI, because if you’re new to something, you probably don’t know anything about it.

I see way too many software projects mess this up. You go to read the documentation, and you’re presented with a huge mass of links and no direction. This is simple to the long-time developer of the project, because a page with lots of links lets that developer quickly go to the part they’re looking for. But for the new person, it’s complicated. On the other hand, for the long-time developer, adding a page with big, simple buttons and eliminating that list of links would add to the complexity of his task, because he’s just trying to find a very specific thing very fast in the documentation.

The only thing worse than complex documentation is no documentation, where you’re just expected to figure it out for yourself or “already know.” To the developer, the way his program works is obvious, but to the new user, it’s totally unknown.

With software, there are all sorts of different viewpoints. Just a few would be: Programmer, QA Engineer, Manager, Support Technician, User, Power User–to all of these people, “simple” will be different.

Context has a lot to do with this too. (Read More…)