The Best Code is No Code At All

Rich Skrenta writes that code is our enemy.


This is a companion discussion topic for the original blog entry at: http://www.codinghorror.com/blog/2007/05/the-best-code-is-no-code-at-all.html

Youā€™re right, that is some good advice.

But something just compells me to use String.Empty vs. ā€œā€! There isnā€™t a reason I could give you other than String.Empty being nicer to look at, and perhaps indicating my intent more clearly (maybe). There is a difference between the two:

http://blogs.msdn.com/brada/archive/2003/04/22/49997.aspx

atleast in .NET. But it is trivial.

It seems like your advice would apply more effectively to reductions in excess lines of code, excess classes, excess levels of abstraction or excess concreteness (filling out an abstraction in too many ways).

But overall, I agree that I am my own worst enemy when writing software.

All true .NET programmers know that you use ā€œif(String.IsNullOrEmpty(s))ā€ (which does, truly have advantages over either of the other methods) :slight_smile:

Other than that, I couldnā€™t agree moreā€¦ brevity and simplicity == maintainability, which is more important that most other aspects of the ā€œqualityā€ of code.

Yes, I would have to agree that engineers need to shorten their scripting, rather that simply ā€œcompressingā€ it to be smaller. I am working with the Prototype.js script, and itā€¦ itā€™s just huge. I have seen versions of it be compressed, and that does workā€¦ but thatā€™s not the direction the code should be going. More attempts should be made to have it be smaller script.

To some, code is less of something to fear, and more of an avenue of expression - expression of intent, business rules, find a mate, love your mother - whatever. Each line is a stroke of a brush on a wide-open canvas, and if youā€™re really good, it can turn out quite well.

You wouldnā€™t want to censor us would you Jeff? Would you cast the same light on this here blog? I think you could have said this whole thing in one sentence, however than it wouldnā€™t have acheived its goal of diverting me (yet again!)

Well, donā€™t we all know that the one true way is ā€“

if (s.Length ==0)ā€¦

Anyway, I would add that along with choosing not to add code or choosing brief code when needed, that code must be pruned often to be healthy. See the Boat Anchor Anti-Pattern.

Iā€™d like to see a metric on how much time Iā€™ve spent looking at dead code not realizing it was dead in my career. In every case, the code is saved ā€œin case we need it later.ā€ Itā€™s a little easier to find now with the IDE and re-sharper and such, but I still see a lot of dead ends, even in recent code.

There is a photography lesson that can be applied here that I saw a while back. Take a picture and a pair of scissors, then cut away everything that is not the subject. Then you have a good picture. Can that be applied to code?

@Barry:

BlogComment: Object reference not set to an instance of an object. ā€” System.NullReferenceException: Object reference not set to an instance of an object.
at BlogComment() Line 1

No offense, but I think both you guys missed the critical point Jeff tried to make. It doesnā€™t matter which one is more ā€œright,ā€ but whether it makes a difference in your code. If you donā€™t need to worry about the distinction, you should use the simpler solution precisely embecause/em itā€™s simpler.

I missed the bullet point that showed beauty as a dimension of codeā€¦ Perhaps the beauty the quoted text was referring to meant that the code was robust and/or flexible.

My guess (hope, actually) would be that if you spent 3 days writing code it would be robust, beautiful and flexible.

As far as coding ā€˜if (s == ā€œā€)ā€™ Iā€™d much prefer using String.IsNullOrEmpty because, in nearly all instances, you donā€™t want a null value treated like a populated string which is exactly what you would get with that check.

We need to spend time designing systems that the average coder simply canā€™t mess up. Many companies claim that they only hire the top 10% of developers (which is obviously false). But with a well designed system you should be able to hire developers right off of the street (at least in theory). If you canā€™t hire entry level developers then you have failed to produce a well designed system.

For example, if you require developers to open and then remember to close database connections then you have failed as an architect. You need to protect programmers from their own stupidity. Heck, even a good developer can forget to close a database connection now and then. And since the end result is connection leakage, we need to take the extra time to ensure that this is handled automatically by the framework. The same can be said for all of the other mundane tasks that programmers often forget (like input validation, etc.). But what do you typically see in enterprise applications? Hundreds of places where database connections are opened and closed and hundreds of places where programmers are required to test input to see if it is a valid date. Yet these things can easily be handled automatically.

I love this blog. I really do. I am not much of a coder. Iā€™ve found to have a natural inclination towards writing code. I started with PHP which I know does not have the gravitas of say .Net or C; however, I am amused by this post as a potential coder.

When I have tried to explain what writing code is like to someone who knows much less about code and computers in general I have two approaches. I say code is like math, like algebra, an equation that has boxes (variables) that hold things (double, int, string, object). I also say that writing code is very much like a language, English, Spanish, French, Japanese, Korean and so forth. There are rules of syntax of structure that a developer must follow in order for a program to function, to be read.

In poetry or lyric writing, which I write none of, the artist has the flexibility to parallel a standard, almost follow a rule. In the above example if (s == String.Empty) if (s == ā€œā€) the artist got a chance to follow what they feel is most beautiful.

As the brilliant mind of this blog points out, you are trying to write reliable robust stuff with as few lines as possible. We need to be practical and adhere to these metrics.

Thinking of code as a human language and writing code in this abbreviated manor gives me a funny feeling. If ever human language were to follow abbreviation, we may find C the NewSpeak of 2084. Then again my English simply sucks.

And here I just thought I was lazy.

Iā€™m not a VisualBasic expert, but I do know about a dozen other languages and in most of these languages, there is a difference between a truly empty, undefined string and a string defined as containing no characters, so

if (s == String.Empty)
if (s == "")

May mean two different things. If variable ā€œsā€ represents the userā€™s answer to a question, I may need to know if the user didnā€™t answer the question, or the user answered the question and the answer is in fact ā€œā€.

Also, if permitted, I think this looks better and reads easier:

if (s.Empty())

I code first so that I can understand the solution and I trust that my first ā€˜solutionā€™ might not be the optimized one. There will be time to make it faster, after it works.

Iā€™m unconcerned about the string.empty versus the ā€œā€ comparision, honestly. That isnā€™t where Iā€™m going to get tripped up. What is going to cause me the most grief is when I decide that Iā€™ve ā€œfigured it all outā€ and fire up Visual Studio prematurely. My best (and usually smallest) programs are the ones where I have raided the paper recycling box and scratched out a solution in pencil instead of going directly into ā€œCode from the Hipā€ mode.

It is easy to get into feature bloat mode and turn what was an elegant solution into something resembling the Winchester Mystery House. That tends to happen when I donā€™t take the time to think through what needs to be done and how it might be done concisely.

I still like the DRY (donā€™t repeat yourself) principle best and try to follow it. That alone has helped me reduce the number of places that could be wrong or might need to be replaced later on.

I disagree, some times writing alot of codeā€¦ that can be refactored will be much easier to read, i know this is one parameter of the equation of ā€œqualityā€ code but still,

ObjType ot = myfactory.GetObjType();
Instant.DoSomething(ot);

orā€¦
Instant.DoSomething(myfactory.GetObjType());

just simple example point out my intentions.

This idea that no code is good code is just the latest fashion in software development practices. Iā€™m all for refactoring, generifying, and generally moving towards metadata, but it can be taken to the wrong extreme.

In the hands of a competent typist using a good IDE, Jeff is talking about microseconds of difference. Add responsible comments to the mix and speed becomes a factor of the programmerā€™s knowledge of English. (when will they put spell-check into Visual Studioā€¦)

I do a lot of work in the CMS area, and all the major vendors are trying to cut custom source code out of the process, replacing it with drop-in controls and XML. This has the effect of actually SLOWING DOWN custom development.

although originally symbolic, (pronounced scripty) the practice of placing data inside an HTML template continues to move towards XSLTā€¦ I seem to remember a lot of early Whidbey literature also pushed declared components as being superior than the 5 lines it takes to bind a DataSet to SqlCommand output. Anyone whoā€™s exercised more than the barest SELECT statement in an asp:DataSource control realizes thereā€™s no efficiency gain.

You want to talk about verbose, try writing the equivalent of a 5 option switch() statement in XSLT. Good luck finding runtime errors in that, or if youā€™re so inclined, I hope you enjoy writing test harnesses, because the move toward stateless programming is a move away from tools with several decades of finesse behind them. A week ago Jeff complained about the C# compiler tax, non-programming introduces the run-to-test tax, and the trace statement tax, which is worse.

I consider the String.Empty debate to be a very small one, since the shift-key stretch takes longer than tabbing between autocomplete options. To that end, Iā€™ve often thought that the best programming language in the world would cut the shift key out of the majority of statements, but still give the brevity of C syntax. Something as simple as replacing { with [, and " with ā€™ would probably give a developer an extra 30 words a minute.

Jeffā€™s example is trivial when you compare ā€œā€ which is something that anyone knows what it is. However, the goal is still to write maintainable code, whatever your definition is of that. But basically when you are writing code, you not writing it for your benefit, your writing it for the next poor schmuck that has to maintain it. Sometimes being the most efficient isnā€™t always easy to maintain.

And this, friends, is why we should code in Python. Everything I do in that language would take three times the lines in Java or C#.

I wrote a 17-line agglomerative clustering algorithm last week. Can your language do that? :slight_smile:

Itā€™s the difference between this:

result = [x**2 for x in source]

and this:

ArrayListInteger result = new ArrayListInteger();
for (x : source) {
result.add(x * x);
}

(Iā€™m sure the C# version is similarly wordy.)

If you donā€™t know this beautiful language, do yourself a favor and take a day to learn it. If code is your enemy, when you donā€™t need serious execution speed, Python is your best friend.

I come at this from a slightly different perspective: Iā€™m a physicist/mathematician/biologist, and I positively abhor writing code. Iā€™m also very good at it, good enough where several times people have offered me jobs out of the blue.

I think that there is too much code, and I think itā€™s for exactly two reasons.

  1. Languages. All present day computer languages are awful. The least awful are Haskell and Pygmy Forth (or ColorForth). Any time a language requires any kind of workaround when translating from mathematics to code, you code grows longer. This is why the steady push to think about programming concepts as objects in category theory is vital. Object oriented programming in its purest form (Smalltalk, Self, and the like) offend as much as C. Arbitrary graphs (relations among objects) are a particularly awkward target for the translation of nontrivial operations.

  2. Programmers donā€™t throw away code enough. When faced with a hunk of code someone else wrote, which doesnā€™t appear to be quite right, or is misbehaving, the proper action is to figure out what itā€™s supposed to do, and its interface, and then scrap it and start from scratch. (Iā€™m not talking about rewriting whole programs here, just sections.) Instead, people try to handle the corner cases, or hunt down where the leak is. Just stop, think for a little while, get the structure well posed, then write that.

Fred makes an excellent point with:

ā€œWhen faced with a hunk of code someone else wrote, which doesnā€™t appear to be quite right, or is misbehaving, the proper action is to figure out what itā€™s supposed to do, and its interface, and then scrap it and start from scratch.ā€

For this, you need to add comments. Lots of programmers hate them: it slows you down, and you already know what the code is supposed to doā€“while youā€™re writing it. But what if you have to revisit the code 10 or 15 years later? It is NOT a nice feeling when you canā€™t figure out your own code.