Code Simplicity

Powered By WordPress
Theme Based On A Design By Jared Quinn.

Laws of Software

Readability and Naming Things

Posted by Max Kanat-Alexander
On January 25th, 2011 at 11:01

Permalink | Trackback | Links In

Category: Laws of Software

Many people think that the readability of code has to do with the letters and symbols used. They believe it is the adding, removing, or changing of those symbols that makes code more readable. In some sense, they’re right. However, the underlying principle is:

Readability of code depends primarily on how space is occupied by letters and symbols.

What does that mean? Well, it means two things: (Read More…)

Software Design, In Two Sentences

Posted by Max Kanat-Alexander
On May 13th, 2010 at 11:05

Permalink | Trackback | Links In

Category: Laws of Software

In the context of The Equation of Software Design, it is now possible to reduce the primary principles of software design into just two statements:

  1. It is more important to reduce the Effort of Maintenance than it is to reduce the Effort of Implementation.
  2. The Effort of Maintenance is proportional to the complexity of the system.

And that is pretty much it. If all you knew about software design were those two principles and the purpose of software, you could evolve every other general principle of software development.

-Max

The Equation of Software Design

Posted by Max Kanat-Alexander
On January 6th, 2010 at 12:01

Permalink | Trackback | Links In

Category: Laws of Software

So today I was playing around with a little equation that may in fact explain nearly all of the principles of software design. (Read More…)

Features, Simplicity, and the Purpose of Software

Posted by Max Kanat-Alexander
On December 12th, 2008 at 10:12

Permalink | Trackback | Links In

Category: Laws of Software

One of the best ways to keep an app simple is, of course, to limit how many features you implement. Twitter, for example, has very few features, but is enormously successful. The limited number of features of Twitter make it really easy to keep the application simple, which lets the developers focus a lot on the quality of the system, the polish of each individual feature, etc.

Twitter’s just one of the many proofs that you don’t have to have lots of features to be successful. In fact, many successful apps have fewer features than their less-successful competitors.

Still, you’ve got to have some features. :-) After all, it’d be pretty silly to be programming, otherwise. But how do you decide which features you should have? Is it just up to the Chief Architect’s intuition, or how many users demand that you give them “feature X”? Does whoever shouts the loudest in the development meeting get their feature implemented first?

Well, no, there is a way to decide whether or not you should implement a feature, and it comes out of one of our most basic principles: the purpose of software. This principle (that the purpose of software is “to help people”) isn’t just some fancy-sounding gibberish I made up to make myself happy–I wrote it because it’s something that can actually be really useful to think about in everyday programming, and this question of “Should we implement this feature?” gives us a great opportunity to show how it can be applied. (Read More…)

(I)SAR Clarified

Posted by Max Kanat-Alexander
On December 1st, 2008 at 12:12

Permalink | Trackback | Links In

Category: Laws of Software

In my previous post, I said that there are three major parts to any computer program: Structure, Action, and Results. Also, a program has Input, which could be considered a fourth part of the program, although usually it’s not the programmer who’s creating the input, but the user. So we can either abbreviate this as SAR or ISAR, depending on whether or not we want to include “Input.”

Now, some people misunderstood me and said, “Oh, SAR is just another name for MVC.” No, I used MVC as an example of SAR, but SAR is a much, much broader concept than MVC–they are not comparable theories. MVC is a pattern for designing software, whereas SAR (or ISAR) is a statement of the three (or four) components that are present in all software.

The fascinating thing about SAR is that it applies not only to a whole program, but also to any piece of that program. A whole program has a Structure, just as a function or single line of code has a Structure. Same for Action and Results.

Here’s a little more about each of the pieces, and some examples to help explain:

Structure

Here are some examples of things that would be considered “Structure” for the whole program: (Read More…)

Structure, Action, and Results

Posted by Max Kanat-Alexander
On November 1st, 2008 at 14:11

Permalink | Trackback | Links In

Category: Laws of Software

There’s a very popular model for designing software that we’ve all heard of if we’re web developers, and probably most desktop developers have heard of too: our old friend MVC. This works well because it reflects the basic nature of a computer program: a series of actions taken on a structure of data to produce a result. Programs also take input, and so you could possibly argue that input was a fourth part of a program, but usually I just think of a computer program as the first three parts: Structure, Action, and Results.

In the MVC sense, the Model is the Structure, the Controller is what does the Actions, and the View is the Result. I think the analogy (and the words) Structure, Action, and Results are more widely and accurately applicable to the operation of every program in existence, though, moreso than MVC, though MVC is a perfectly good way of looking at it for GUI applications.

Really, Structure, Action, and Results probably describes almost any machine in existence. A machine has some parts that don’t move, a framework–that’s the structure. Some parts move and do something–that motion is the action. And of course the machine produces something (otherwise we wouldn’t care much about it) so that’s the result.

Computer programs are unusual machines in that they can modify their own structure. However, it’s important that some part of the program be stable, that they “not move” in a logical sense. The way that object classes relate to each other, the names of methods and variables–these are all parts of the structure that usually don’t change while you’re running. (Sometimes you make new classes, methods, or variables while you’re running, but they usually follow some pre-set plan, so there’s still a lot of “not moving” involved.)

When I’m writing software, I usually build the Structure first, then I work on the Actions, and then I work on the displaying of the Result. Some people work backwards from the Results, that’s fine too. Probably the only inadvisable thing to do is to start with the Actions, since it’s kind of confusing to be performing Actions without a Structure and with no defined Result.

There’s so much to this concept that I could probably write a whole book just on this one topic, but I think this is a decent introduction, and I’m sure that given this, you can think of lots of other useful applications of it.

-Max

Simplicity and Security

Posted by Max Kanat-Alexander
On October 17th, 2008 at 12:10

Permalink | Trackback | Links In

Category: Laws of Software

A big part of writing secure software (probably the biggest part) is simplicity.

When we think about software security, the first question that we ask is, “How many different ways could this program possibly be attacked?” That is, how many “ways in” are there? It’s a bit like asking “How many doors and windows are there on this building?” If your building has 1 exterior door, it’s very easy to protect that door. If it has 1000, it will be impossible to keep the building secure, no matter how good the doors are or how many security guards you have.

So we need to limit the “ways in” to our software to some reasonable number, or it won’t ever be secure. That’s accomplished by making the overall system relatively simple, or breaking it down into very simple and totally separate component parts.

Then, once we’ve limited the ways in, we need to start thinking about “How many different possible attacks are there against each way in?” We limit that by making the ways in themselves very simple. Like a door with only one unique key, instead of a door that can take five different keys, all of which individually will open the door.

Once that’s done, we limit how much damage any attack could do if it got through. For example, in a building, we’d make any given door only allow access to one room.

All of this explains, for example, why Windows is fundamentally flawed and will never be secure, and why UNIX-based systems have a better reputation for security. (Read More…)

What Is A Computer?

Posted by Max Kanat-Alexander
On October 10th, 2008 at 10:10

Permalink | Trackback | Links In

Category: Laws of Software

What is a computer? You’d think that would be a fairly simple question. After all, I’m using one to type this up, I ought to know what it is, right? I mean obviously, it’s a…computer! I mean, it’s got a keyboard, and a monitor, and there’s that box down there…

But what is it that makes all that stuff a computer? Why do we look at it and go, “Oh yeah, that’s a computer,” as opposed to, say, “Oh, that’s just a TV,” or “That’s where I keep the leprechauns at night.”?

Some people try to define the word “computer” just by saying “it’s got such and such parts and they all work this way,” but that’s like saying “airplanes have two wings and jet engines.” It’s true, but I could build an airplane that didn’t have two wings or jet engines. The way something works is not a definition for that thing.

Others try to define it mathematically, but that can also be somewhat limiting, because then only the devices that fit into your mathematical scheme are computers, and there are multiple mathematical models that would all be considered “computers.”

So I turned to the dictionary. That was fun for me–I’m a dictionary fanatic. I’ve got lots of great dictionaries, and there are even more online. The Compact Oxford English Dictionary had the best definition, as it turned out.. I was very happy with it at first, but when I started to think about it, it didn’t quite work. For example, it calls computers “an electronic device,” and we know that computers can be built without electronics.

So I worked to come up with a definition of my own. Strangely enough, the key question that it boiled down to was “Why is a player piano not a computer?” It “processes information” by playing notes from its roll. If you gave it an etching machine, it could “store information” back on to the roll. But despite all that, it’s clearly not a computer. What is a computer doing that is fundamentally different from a player piano, that a player piano could never do? (Read More…)

Sane Software Design

Posted by Max Kanat-Alexander
On August 11th, 2008 at 11:08

Permalink | Trackback | Links In

Category: Laws of Software

I have come up with an analogy that should make the basic principles of software design understandable to everybody. The great thing about this analogy is that it covers basically everything there is to know about software design. (Read More…)

The Source of Bugs

Posted by Max Kanat-Alexander
On July 21st, 2008 at 11:07

Permalink | Trackback | Links In

Category: Laws of Software

Bugs most commonly come from somebody’s failure to reduce complexity. Less commonly, they come from the programmer’s misunderstanding of something that was actually simple.

Other than typos, I’m pretty sure that those two things are the source of all bugs, though I haven’t yet done extensive research to prove it.

When something is complex, it’s far too easy to misuse it. If there’s a black box with millions of unlabeled buttons on it, and 16 of them blow up the world, somebody’s going to blow up the world. Similarly, in programming, if you can’t easily understand the documentation of a language, or the actual language itself, you’re going to mis-use it somehow.

There’s no right way to use a box with millions of unlabeled buttons, really. You could never figure it out, and even if you wanted to read the 1000-page manual, you probably couldn’t remember the whole thing well enough to use the box correctly. Similarly, if you make anything complex enough, people are more likely to use it wrongly than to use it correctly. If you have 50, 100, or 1000 of these complex parts all put together, they’ll never work right, no matter how brilliant an engineer puts them together.

So do you start to see here where bugs come from? Every time you added some complexity, somebody (and “somebody” could even be you, yourself) was more likely to mis-use your complex code. Every time it wasn’t crystal clear exactly what should be done and how your code should be used, somebody could have made a mistake. Then you put your code together with some other code, and there was another chance for mistakes or mis-use. Then we put more pieces together, etc.

Often, this sort of situation happens: the hardware designer made the hardware really complicated. So it had to have a complicated assembly language. This made the programming language and the compiler really complicated. By the time you got on the scene, you had no hope of writing bug-free code without ingenious testing and design. And if your design was less than perfect, well…suddenly you have lots of bugs.

This is also a matter of understanding the viewpoint of other programmers. After all, something might be simple to you, but it might be complex to somebody who isn’t you.

If you want to understand the viewpoint of somebody who doesn’t know anything about your code, find the documentation of a library that you’ve never used, and read it.

Also, find some code you’ve never read, and read it. Try to understand not just the individual lines, but what the whole program is doing and how you would modify it if you had to. That’s the same experience people are having reading your code. You might notice that the complexity doesn’t have to get very high before it becomes frustrating to read other people’s code.

Now, once in a while, something is really simple, and the programmer just misunderstood it. That’s another thing to watch for. If you catch a programmer explaining something to you in a way that makes no sense, perhaps that programmer misunderstood something somewhere along the line. Of course, if the thing he was studying was extremely complex, he had basically no hope of fully understanding it without a PhD in that thing.

So these two things are very closely related. When you write code, it’s partially your responsibility that the programmer who reads your code in the future understands it, and understands it easily. Now, he could have some critical misunderstanding—maybe he never understood what “if” meant. That’s not your responsibility. Your responsibility is writing clear code, with the expectation that the future programmer reading your code understands the basics of programming and the language you’re using.

So, there are a few interesting rules that you can get out of this one:

The simpler your code is, the fewer bugs you will have.

Always work to simplify everything about your program.

-Max