This site will look much better in a browser that supports web standards, but is accessible to any browser or Internet device.

Anomaly ~ G. Wade Johnson Anomaly Home G. Wade Home

August 25, 2007

Form vs. Style

Ever since O'Reilly published the new book Beautiful Code, there seem to be references everywhere to what makes code beautiful. While a few people have suggested that beauty should not influence code (see the comments section for the suggestion that there is no beautiful code), I believe that most people have seen code that they thought was particularly well done, and might even be considered beautiful.

I suspect that most people focus on the wrong thing when then think of beautiful code. I would like to separate what most people consider beautiful into two parts: form and style. By form, I mean the fundamental design or structure of the code.

  • Does it solve the problem at hand?
  • Is it understandable?
  • Is it as simple as possible, but no simpler?
  • etc.

On the other hand, style refers more to issues that may be important, but are less fundamental.

  • Does it follow the coding guidelines of the group?
  • Is it written in the appropriate language?
  • Is it a clever or cool solution?
  • etc.

Many people focus too much on style at the expense of form. I think that is partly because style is easier to codify than form. Almost anyone can enforce a brace style or naming convention, but making or recognizing a simple solution is much harder. Programmers are also attracted to complexity and are often seduced by clever solutions.

The real downside is that people often try to fix a bad form by piling on more style. This never generates a beautiful solution, but it might obscure the extent of the bad form. Like the fins on a 1950's Cadillac, it looks cool now, but it won't look as good later.

Ugly Code

I don't usually write beautiful code. I do focus hard on the form, but I am rarely completely happy with my solutions. Despite this, I feel I have some advantage in this area. Early in my career, I was exposed to quite a bit of atrocious code. This code depended heavily on global variables, misused language idioms, and preserved old code mistakes as running comments in the code. It was hard to read and difficult to maintain.

This code formed the basis of my desire to improve, I never want to leave behind code like that. Over the years that followed, I tried to hone my skills at recognizing what I called good code.

Beautiful Code

At one point, I was working with a promising young programmer on a redesign of an important part of the system we were maintaining. We had spent time discussing the requirements and had mostly worked out the general shape of the solution we would use. At that point, I needed to leave for the day and we agreed to work on it some more the next day. I came in early the next morning and took a look at the code. She had laid out the beginnings of the code without filling in all of the details. Each major piece of functionality had its own well-named function. Higher level functionality was built in terms of the lower level pieces. Every function had a clear name that explained the function's responsibility. The general gist of the design was already in place with placeholders for anything that we had not had a chance to work out.

This was by far the most beautiful code I had ever seen. I actually dragged another senior programmer over to see this code. The style was not yet perfect, There were many levels of stuff that could have been added on top of this code. But, the form of the solution would have been obvious to anyone seeing the code. As we worked over the next few weeks, we did make some comprises that marred the initial beauty of the code and we layered on some style to make the result a bit prettier. In the end, the original beauty remained mostly intact and visible.

Evaluating Code

I've used that code as my yardstick ever since. I may not write beautiful code every time, but I have good examples of beautiful and ugly code in mind that serve as my guides. As I write code, I try to evaluate my code against those examples.

Posted by GWade at 10:24 PM. Email comments

August 04, 2007

The Flaw of Everything is an Object

Several newer languages (as in less than 10 years old) have been designed around the idea that everything is an object. Since I started programming professionally almost two decades ago, I was programming before the object craze became mainstream. I have done the OO thing for over a decade and am not as impressed as I once was.

Although not everyone will agree with me, I suspect that OO is not always the best choice. In fact, in some applications, a simple, straight-forward procedural approach is better.

Many OO advocates will point out that the procedural approach doesn't scale. They tend to forget that a large fraction of the code written in the world doesn't need to deal with terabytes or petabytes of data. Much code isn't called thousands of times a second. Even more code is not mission critical. And some applications run on systems without the resources for the overhead of OO.

Learning OO

I also find that the object approach appears to be harder for people to really master. Many people claim to have learned OO programming in a few weeks, but it seems to take at least two years for people to really get it. Before that point, new OO programmers end up creating collections of data and methods with no cohesion or multiple classes with intimate knowledge of each other's inner workings. It usually even takes a few months before they stop inheriting everything just because they can. I won't even discuss the objects that serve only as a holder of a handful procedural programming methods that show no signs of abstraction.

On the other hand, I've seen non-programmers pick up a little bit of procedural programming relatively quickly. Just enough to automate some portion of their computer usage and save a little time. This is some of the appeal of many of the dynamic languages. It's easier to whip out a little code to get a job done. Would I recommend this kind of programming for life- or mission-critical applications? No, but that doesn't make it useless.

Not The One True Way

I suspect that to objects have become the latest Golden Hammer in our field. It has also been around long enough that people have worked in the OO paradigm long enough that they have begun to believe that there is nothing else.

As such, people tend to forget that the is overhead involved with using OO. I'm not just talking about memory and CPU overhead. While it is true those forms of overhead exist, both are getting cheaper fast enough that they are not the major problem (unless you are doing embedded systems). The more important overhead is conceptual. Everyone starts with the obvious (and incorrect premise) that programming objects are just like objects in the real world. This view of objects is easy to understand, but very limited. Amusingly enough, in the real world it is obvious that everything is not an object. Energy, thoughts, emotion, and probability are fundamentally different than a table or cup. Forcing them into the same framework would not make much sense.

Concepts

In most of the OO programming I've have done or seen only a tiny fraction of the classes have anything to do with real physical objects. I think the best breakthrough for me was the comment concepts are classes in the book Ruminations on C++ by Koenig and Moo. This finally solidified for me the non-real world things that need to classes. I had done this many times without really having a reason. Wrapping your mind around these concepts and learning to work with them seems to take months to years for every programmer I've ever worked with, taught, or mentored. Along the way, they normally reach several Aha! moments that move them toward real ability with OO.

This does not sound like the best approach for people who are just beginning to learn to program or for people who only need to program as a sideline to get their real work done.

Even in the most fanatical of OO programming languages, we eventually reach the level of individual statements. These are not objects, and making them objects would increase the difficulty in understanding. However, most people overlook that.

Language Feature?

I have come to believe that the everything is an object meme has nothing to do with ease of learning or use of the language. I suspect that the approach only simplifies things for the language designer. After all, as a user of the language, how does having an integer be an object really make your coding or design easier. In order to make the code usable, these integer objects either need special syntactic support in order for us to write mathematical expressions somewhat naturally, or the language needs support for operators built in to the classes. Both complicate the language for the (marginal) benefit of being able to say that all of my numbers are objects, just like everything else.

As a rule, I find this assertion to be a quirk of a given language rather than a particular bonus; kind of like Lisp's parenthesis, C++'s templates, or Perl's punctuation variables. They are part of the language and are only good or bad in as much as they help or hinder my ability to learn the language and read and write useful code.

Posted by GWade at 10:49 AM. Email comments