Posts tagged as:

Simplicity

Abstractions are never perfect

by John on January 11, 2010

Better to have a simple system than a complex system with a simple abstraction on top.

Abstractions are never perfect. Every new layer creates failure points, interoperability hassles, and scalability problems. New tools can hide complexity, but they can’t justify it … The more complex the system, the more difficult it is to fix when something goes wrong.

From the preface to RESTful Web Services.

Related posts:

Obscuring complexity
Baklava code
Leaky abstractions
Less isn’t more; just enough is more

{ 0 comments }

Conservation of complexity

by John on September 16, 2009

Larry Wall said something one time to the effect that Scheme is beautiful and every Scheme program is ugly; Perl is ugly, but it lets you write beautiful programs. Of course it also lets you write ugly programs if you choose.

Scheme is an elegant, minimalist language. The syntax of the language is extremely simple; you could say it has no syntax. But this simplicity comes at a price. But because the language does so little for you, you have to write the code that might have been included in other languages. And because the language has no syntax, code written in Scheme is hard to read. As Larry Wall said

The reason many people hate programming in Lisp [the parent language of Scheme] is because every thing looks the same. I’ve said it before, and I’ll say it again: Lisp has all the visual appeal of oatmeal with fingernail clippings mixed in.

The complexity left out of Scheme is transferred to the code you write in Scheme. If you’re writing small programs, that’s fine. But if you write large programs in Scheme, you’ll either write a lot of code yourself or you’ll leverage a lot of code someone else has written in libraries.

Perl is the opposite of a minimalist language. There are shortcuts for everything. And if you master the language, you can write programs that are beautiful in that they are very concise. Perl programs can even be easy to read. Yes, Perl programs look like line noise to the uninitiated, but once you’ve learned Perl, the syntax can be helpful if used well. (I have my complaints about Perl, but I got over the syntax.)

Perl is a complicated language, but it works very well for some problems. Features that other languages would put in libraries (e.g. regular expressions, text munging) are baked directly into the Perl language. And if you depend on those features, it’s very handy to have direct support in the language.

The point of my discussion of Scheme and Perl is that the complexity has to go somewhere, either in the language, in libraries, or in application code. That doesn’t mean all languages are equal for all tasks. Some languages put the complexity where you don’t have to think about it. For example, Java simpler than C++, as long as you don’t have to understand the inner workings of the JVM. But if you do need to look inside the JVM, suddenly Java is more complex than C++. The total complexity hasn’t changed, but your subjective experience of the complexity increased.

Earlier this week I wrote a post about C and C++. My point there was similar. C is simpler than C++, but software written in C is often more complicated that software written in C++ when you compare code written by developers of similar talent. If you need the functionality of C++, and most large programs will, then you will have to write it yourself if you’re using C. And if you’re a superstar developer, that’s fine. If you’re less than a superstar, the people who inherit your code may wish that you had used a language that had this functionality built-in.

I understand the attraction to small programming languages. The ideal programming language has everything you need and nothing more. But that means the ideal language is a moving target, changing as your work changes. As your work becomes more complicated, you might be better off moving to a more complex language, pushing more of the complexity out of your application code and into the language and its environment. Or you may be able down-size your language because you no longer need the functionality of a more complex language.

Related posts:

Three-hour-a-week language
Plain Python
MIT replaces Scheme with Python
Periodic table of Perl operators
Programming language subsets

{ 0 comments }

Software that gets used

by John on July 31, 2009

I’ve been looking back at software projects that I either developed or managed. I thought about which projects produced software that is actively used and which didn’t. Here’s what the popular projects had in common. The software

  1. was developed to address existing needs, not speculation of future needs;
  2. solved a general problem; and
  3. was simple, often controversially simple.

The software used most often is a numerical library. It addresses general problems, but at the same time it is specialized to our unique needs. It has some functions you won’t find in other libraries, and it lacks some functions you’d expect to see but that we haven’t needed.

A couple of the more successful projects were re-writes of existing software that deleted maybe 90% of the original functionality. The remaining 10% was made easier to use and was tested thoroughly. No one missed the deleted functionality in one project. In the other, users requested that we add back 1% of the functionality we had deleted.

Related posts:

Simple legacy
The simplest thing that might work

{ 1 comment }

Simplicity quote

by John on May 20, 2009

Quote from Julian Barnes:

There is something infinitely touching when an artist, in old age, takes on simplicity. The artist is saying: display and bravura are tricks for the young, and yes, showing off is part of ambition; but now that we are old, let us have the confidence to speak simply.

HT: Signal vs. Noise

{ 0 comments }

Simple legacy

by John on October 15, 2008

Benoit Mandelbrot makes the following observation in The Fractal Geometry of Nature.

Many creative minds overrate their most baroque works, and underrate the simple ones. When history reverses such judgments, prolific writers come to be best remembered as authors of “lemmas,” of propositions they had felt “too simple” in themselves and had to be published solely as preludes to forgotten theorems.

If you’re not familiar with lemmas and theorems, think of a musician who is famous for a short prelude written as an introduction to a longer piece nobody remembers. For example, Rossini’s four-minute William Tell Overture is far more famous than the four-hour William Tell opera it introduces.

Returning to famous mathematicians, I remember as an undergraduate hearing of Schwarz’s lemma and waiting for the corresponding theorem that never came. The same applies to Poincaré’s lemma, Zorn’s lemma, and Fatou’s lemma.

We’re all naturally proud of things we work hard for. We expect other people to value our work in proportion to the amount of effort we put into it, but the world doesn’t work that way. It can be discouraging focus on the big, complex projects we’ve worked on that haven’t been appreciated. On the other hand, it can be very encouraging to think of the potential impact of small projects and simple ideas.

{ 5 comments }

Conflicting ideas of simplicity

by John on August 12, 2008

Sometimes it’s simpler to compute things exactly than to use an approximation. When you work on problems that cannot be computed exactly long enough, you start to assume everything falls in that category. I posted a tech report a few days ago about a problem in studying clinical trials that could be solved exactly even though it was commonly approximated by simulation.

This is another example of trying the simplest thing that might work. But it’s also an example of conflicting ideas of simplicity. It’s simpler, in a sense, to do what you’ve always done than to do something new.

It’s also an example of a conflict between a programmer’s idea of simplicity versus a user’s idea of simplicity. For this problem, the slower and less accurate code requires less work. It’s more straight-forward and more likely to be correct. The exact solution takes less code but more thought, and I didn’t get it right the first time. But from a user’s perspective, having exact results is simpler in several ways: no need to specify a number of replications, no need to wait for results, no need to argue over what’s real and what’s simulation noise, etc. In this case I’m the programmer and the user so I feel the tug in both directions.

{ 0 comments }

Classroom exercises always have nice, tidy solutions. So students implicitly assume that all problems have nice, tidy solutions. If the solution isn’t working out simply, you must have made a mistake.

Outside the classroom, applications seldom have simple solutions. So after a while you get jaded and quit trying to find a simple solution. But sometimes real problems do have simple solutions, or at least simpler solutions than seemed possible.

The Extreme Programming folks have a saying “Try the simplest thing that could possibly work.” If that doesn’t work, then try the next simplest thing that could possibly work. That line of thinking has paid off a few times lately.

I’ve had a couple math problems that I first assumed had to be approximated numerically that were more easily computed exactly. And I’ve had a couple programs where I was able to debug a section of code by simply deleting it. Things don’t always work out that well, but it’s fun when they do.

{ 0 comments }

A little simplicity goes a long way

by John on April 9, 2008

Sometimes making a task just a little simpler can make a huge difference. Making something 5% easier might make you 20% more productive. Or 100% more productive.

To see how valuable a little simplification can be, turn it around and think about making things more complicated. A small increase in complexity might go unnoticed. But as complexity increases, your subjective perception of complexity increases even more. As you start to become stressed out, small increases in objective complexity produce big increases in perceived complexity. Eventually any further increase in complexity is fatal to creativity because it pushes you over your complexity limit.

Graph of perceived complexity as a function of objective complexity

Going back to simplification, a small decrease in complexity can be a big relief if you’re stressed out. Maybe that small simplification can pull you out of F-state back to C-state. If you’re up against your maximum complexity, a small simplification could make the difference between a problem being solvable rather than unsolvable.

Small simplifications are often dismissed as unimportant when they’re evaluated in the small. Maybe a new term makes it possible to refer to an idea in three syllables rather than six. No big deal if it’s a term you don’t use much. But if it’s a term you use all the time, it makes a difference. That’s why every group has its own jargon.

Suppose one programming language takes five lines of code to do what another language can do in four lines. So what? How long does it take to type one line of code? But multiply that by 10. Maybe you see 40 lines of code on your laptop at once but you can’t see 50. Or multiply by 10 again. Maybe you can hold 400 lines of code in your head but you can’t hold 500. Language features dismissed as “syntactic sugar” can make a real difference.

{ 2 comments }

Three quotes on simplicity

by John on April 9, 2008

It’s easy to decide what you’re going to do.  The hard thing is deciding what you’re not going to do.
Michael Dell

Clutter kills WOW.
Tom Peters

Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius — and a lot of courage — to move in the opposite direction.
Albert Einstein

{ 0 comments }

Perlis on complexity

by John on March 29, 2008

From Alan Perlis:

Fools ignore complexity. Pragmatists suffer it. Some can avoid it. Geniuses remove it.

 See this site for a list of other epigrams from Perlis.

{ 0 comments }

The simplest thing that might work

by John on March 24, 2008

Ward Cunningham’s design advice is to try the simplest thing that might work. If that doesn’t work, try the next simplest thing that might work. Note the word “might.”

We all like simplicity in theory, and we may think we’re following Cunningham’s advice when we’re not. Instead, we try the simplest thing that we’re pretty sure will work. Solutions usually get more complex as they’re fleshed out, so we miss out on simple solutions by starting from an idea that is too complex to begin with.

Once you have a simple idea that might work, you have to protect it. Simple solutions are magnets for complexity. People immediately suggest “improvements.” As design guru Donald Norman says “The hardest part of design … is keeping features out.”

{ 1 comment }

Interview with Ward Cunniningham

by John on March 22, 2008

A professor told me one time that you’re lucky if you have one good idea in your career. He said he was famous because he’d had two or three good ideas.

Ward Cunningham has had at least two good ideas. He created the first Wiki and developed Extreme Programming. The FLOSS Weekly podcast has an interview with Cunningham. The interview shows how closely related Wikis and Extreme Programming are, how both flow naturally from Cunningham’s way of thinking.

{ 1 comment }

Simple unit tests

by John on March 20, 2008

After you’ve read a few books or articles on unit testing, the advice becomes repetitive. But today I heard someone who had a few new things to say. Gerard Meszaros made these points in an interview on the OOPSLA 2007 podcast, Episode 11.

Test code should be much simpler than production code for three reasons.

  1. Unit tests should not contain branching logic. Each test should test one path through the production code. If a unit test has branching logic, it’s doing too much, attempting to test more than one path.
  2. Unit tests are the safety net for changes to production code, but there is no such safety net for the tests themselves. Therefore tests should be written simply the first time rather simplified later through refactoring.
  3. Unit tests are not subject to the same constraints as production code. They can be slow, and they only have to work in isolation. Brute force is more acceptable in tests than in production code. 

(Meszaros made points 1 and 2 directly. Point 3 is my interpolation.)

A well-tested project will have at least as much test code as production code. The immediate conclusion too many people draw is that therefore unit testing doubles the cost of a project.  One reason this is not true is that test code is easier to write than production code for the reasons listed above. Or rather, test code can be easier to write, if the project uses test-driven development. Retrofitting tests to code that wasn’t designed to be testable is hard work indeed.

{ 0 comments }