Continue Discussion 131 replies
May 2007

GuyN

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.

May 2007

Mike_Thomas

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.

May 2007

Josh

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.

May 2007

Rob_Conery

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!)

May 2007

Barry

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?

May 2007

Haacked

@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

May 2007

Frank

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.

May 2007

scotto

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.

May 2007

Matt

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.

May 2007

omegared

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.

May 2007

Goatrider

And here I just thought I was lazy.

May 2007

DavidW

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())
May 2007

Matt_Cuba

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.

May 2007

Adel

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.

May 2007

Rick_Cabral

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.

May 2007

Tim

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.

May 2007

trousercuit

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.

May 2007

Fred_Ross

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.

May 2007

Izzy

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.

May 2007

JonathanA

(I’m sure the C# version is similarly wordy.)

Wrong.

var result = from x in source select x*x;

Of if you perfer VB:

Dim result = From x In source Select x^2

And since it result is a query, you don’t waste time calculating all the values if you happen to only need the first 5.

May 2007

Hk116

Well,
I think that a lot of discussions about minimal semantic differences in short code results from bad compilers as well. As I read in some link, comparing to “” pulls an object from the internal string pool, while String.Empty just checks for emptyness. However, why is a compiler not able to recognize a foo == “” and replace it with foo == String.Empty? That should not be that hard imo. And it whould allow Programmers to just write their style and get the most efficient code out of it.

Furthermore, I cannot agree more on the second part Fred mentioned. Atm, we have some coding course and we are supposed to solve acm-problems. In some very hard problems its just more efficient to just throw the whole solution into the bin and start again if it has some serious bugs. Usually its just harder to track down those bugs and fix them (fixing them usually results in a 90% rewrite anyway) then just to think a minute about the right solution and coding that down. And, code that was written in 1 walk usually looks cleaner than code that went through massive bugfixing. (Ok, I have to use std-c, thus, the code usually looks akward, but oh well…)

MfG

May 2007

StewartJ

You had me up until your String.Empty vs “” example.

Every time you use “” the compiler creates a new empty string to compare your string against. If you make that comparison 100 times then you create destory 100 objects with “” in them.

If you use String.Empty then you’re comparing against the one static “” created and maintained by the String class.

May 2007

codinghorror

Every time you use “” the compiler creates a new empty string to compare your string against.

Not in .NET 2.0 or greater, it doesn’t. Are you smarter than the runtime?
http://www.codinghorror.com/blog/archives/000031.html

If you’re into micro-optimizations, then go here:
http://www.codinghorror.com/blog/archives/000185.html

Warning: the time spent reading is far, far greater than the .00000001 seconds you’ll save with said optimization.

May 2007

Edward

As Shakespeare put it in Hamlet

“Brevity is the soul of wit”

May 2007

Steve

Thanks for reminding me again why I love Perl so much. :slight_smile:

May 2007

karl10

Well, I thought I knew what (s=="") meant, but now I sure don’t.

If s is uninitialized, will it return true or false?

Thanks Jeff.

May 2007

GregM

Here is another of my BRILLIANT SUGGESTIONS, lol:

Jeff – could you write a blog entry about GOOGLING FOR ERROR MESSAGES? This turned out to be an extremely powerful debugging technique for me. I just came across it again and I realized … if I had a blog I’d write about it and other cool things, but you’re the man! Instead of spending time setting up my own blog about tech stuff and having 5 people read it, I readily admit that I am much too lazy for that. But I think it’s a fascinating thing no one has really talked about in depth yet.

For example, today I was working with the symfony framework, trying to use the propel library to translate a schema I had written in yml to an actual database. I wrote the yml file, invoked propel… and I got the following error:

[sfException]
Incorrect settings for column order.

Oops! What is a boy to do? Peer into the source? Au contraire* , I quickly made use of the web and other people’s experience with the problem, by googling for the exact phrase. Nothing. Hmm! So I googled for a substring, which happened to be “Incorrect settings for column”. And sure enough, I found quotes like “Incorrect settings for column $col_name”. Aha, that’s right… I probably had a column named “order” in my .yml file! I quickly glanced at it and sure enough, there was the error. Incidentally, after I fixed it, I got another error message, this time saying “Incorrect settings for column name.”

Thank you google and fellow programmers.

May 2007

SchalkV

Smart code is not about saving execution time, smart code is in not duplicating what you have done already, optimization must only be brought in at bottlenecks. Having inherited a huge code base with areas where I have already optimized the code into a third of the original amount by taking duplication away I can’t agree more with code smaller. A third of the size and not yet even great code. In the same application there is also speed issues in sections, but I expect the Issues to be lessened by removing bad code.

June 2007

John

Well, I prefer

if (s.Length == 0) …

/because/ it crashes for a null string. I almost never want a null string treated as equivalent to an empty one – the latter is a real value, the former is probably a not yet set up variable.

Far better a reliable crash which I’ll find and fix at development time than a program which quietly goes about its way and does the wrong thing.

June 2007

Bob

It seems that it would make sense to move toward higher-level languages that do more with less. I’m more a sysadmin than developer so I gravitate more to Ruby/Perl/Python sorts of languages than C#/Java/C++/C languages, but I treat the former as first-class languages rather than a more powerful shell. Despite whatever performance hit you might take with Perl (and compared to Java, it’s a wash), you get a more expressive language per line of code, even without resorting to baffling idioms, side-effects, and mind-bendingly terse code. Remember, C was designed for systems programming, not application development and that’s a disadvantage shared by all languages that inherit from it.

You’re wasting your time second-guessing a compiler. If performance matters then you need to profile your code and hit up Knuth or Sedgewick for a better algorithm or design.

I don’t do C# or .NET [1] or so I have nothing to add to the ‘which code fragment is better’ argument other than to ask what condition the developer really means to test for, and what the language reference manual says about the different tests suggested. I’d worry about a language that doesn’t optimize “” into a constant, though if “” is created and destroyed in each iteration of a loop, is it affecting performance enough to care about? How would you know?

Then again, I’m a sysadmin. My job is cleaning up after developers; rarely do they ask me for advice. :slight_smile:

[1] Frankly, if all my Windows servers disappeared tomorrow I’d take that as evidence of a benevolent, omnipotent deity.

June 2007

Masklinn

blockquotepEvery new line of code you willingly bring into the world is code that has to be debugged, code that has to be read and understood, code that has to be supported./p/blockquote
pAnd once again, Dijkstra was right on the money:/p
blockquotep[…] If we wish to count lines of code, we should not regard them as emlines produced/em but as emlines spent/em: the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger./p/blockquote

June 2007

Masklinn

Every new line of code you willingly bring into the world is code that has to be debugged, code that has to be read and understood, code that has to be supported.

And once again, Dijkstra was right on the money:

[…] If we wish to count lines of code, we should not regard them as “lines produced” but as “lines spent”: the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger.

June 2007

David_E

To take the analogy one step further…
Programmers tend to see every problem as a program, DBA’s see every problem as a database and IT guys see every problem as a Network.
Sometimes we are guilty of concentrating on modeling the business process so intently that we forget to examine the business process itself and possibly eliminate the need to build the system in the first place ….
My first questions that I ask now are: why do you need it, what does it do, and is there a better way to do it.
You would be surprised how often we have solved the problem without cutting one line of code…
(I am embarrassed to admit that my boss, an MBA taught me this lesson)

June 2007

Andy

Personally, I find String.Empty much easier to read, but that’s a bit of a religious issue.

I don’t think Jeff is talking about Brevity - and I think he even says that - but about Clarity. Clarity is simple, obvious, and to the heart of the matter. Real clarity is brief, but easy to read. That includes comments, too.

It could be made shorter in ‘text speak’, but how clear are those messages? There is a reason we don’t use 1 letter variable names!

It’s not tiny fragments of obscure code that does massive amounts (yes, I’m thinking of Perl in that, amongst others). And it sure as hell isn’t about lines of code - many languages (with notable exceptions) let you put an entire program on one line. Ever tried reading one? I did - you can’t.

It’s just about being simple, clear, and to the point. It’s kind of like Buddhist enlightnment - someday, with enough practice, I’d might just achieve that.

Unfortunately, I do think that we’re constrained - people often expect very complex things and lots of features from their software, and when people are demanding complex programs, you get complex code. Look at the complexity cost of, say, just having a simple UI for a Windows app, as opposed to a console app. Mickey is right - often, we’re trapped by bloated design. KISS is my watchword (and occasionally gets me a slap too).

Fred Ross is right, too, in his comment about code maintenance - but he does miss the point that often we’re under pressure from the boss to ‘just get it done’, and the idea of ‘get it done, but in a way that will save us time later’, well, usually, that dog won’t hunt.

June 2007

Chris

The performance difference between “” and String.Empty, whatever it may be, is irrelevant when your code is waiting on a database, or file I/O, or any number of other things that are orders of magnitude slower.

I find the brevity argument a bit silly. If saving 10 characters is “brief”, why not delete all comments, indentation and blank lines, and rename all variables to a single character? That’s even briefer!

I mostly use String.IsNullOrEmpty() because it clarifies my intent to the next developer. Simple as that.

June 2007

Dan

As to string.empty vs “”, there is a difference: every time you create a literal, NET has to allocate a bit of memory and assign it to “”, which then gets pointed to by your stack variable. If you happen to have lots of “” uses, well, that’s a bit 'o wasted memory; with String.Empty, the one constant is shared

June 2007

JeanH

if s

June 2007

param

Interesting. I think the example given here has proved the point which this column wanted to prove. You see there are at least 10 entries discussing the pros and cons of those 2 (just two) lines of code. In real life, this is the time wasted and it did happen here also. Why? I don’t know!

The problem with software development and of course with software developers is that nobody wants to understand existing code. It is difficult and more difficult when you do not have any documentation, which is true in 90% cases.

I think it all starts with software requirements. The more you understand those requirements the more correct code you will write. If requirements are vague, you will end up writing crap. This is like some soup recipe. If recipe itself is wrong, so is your soup!!
My personal experience is wherever I spent some time understanding the exact requirements, I ended up with good code; with all the documentation and to my surprise the code was very simple and straigtforward.

June 2007

SebastiaoB

A very important feature of code is its readability. Damian Conway (Perl 6 designer with Larry Wall) keeps saying that we read code many more times than we write it. So write it to be readable. Brevity and expressiveness are dimensions to get there.

June 2007

Bill159

Although I agree with most of all people here and I would use String.Empty, I dont think the reason is clarity. s=="" compared to s==String.Empty in terms of clarity comparison is not the same as a single letter named variable versus a clear-purpose named variable. It is not the reasonwhy we should not use “”. The reason depends on the importance of the project and how many times we estimate that this snippet which contains s=="" will appear in our code. The mistake I see in Jeff’s example (and strictly to this specific example) is that does not take advantage of a ‘bonus, free of charge’ abstraction level that the framework offers him. Even if he does not need it now, he may need it in the future.

I would accept Jeff’s opinion if he could guarantee that “”==String.Empty all the time. In his example he assumes this, propably because he has something specific in his mind, like an example code snippet to illustrate an opinion. But in our minds “” may not be equal to String.Empty because of our reasons. If I need a small app to do a simple thing just for once then “”==String.Empty is true, but if I need a bigger app and I have the slightest doubt that I will do that comparison of s with “” or String.Empty only once in my code then I will definitely use the String.Empty abstraction of “” that the framework donates to me. I am thinking that I will be able to redefine String.Empty and change its meaning in one place. I wont have to search for “” and replace it by “0” just because a damn scanner reports “0” instead of “” when it scans a product with no serial number given yet.

I know I could have descrideb my opinion more briefly but I dont know the english language framework so well :slight_smile:

June 2007

Bill160

And whats more, If that damned scanner was used after I abandoned the code and someone else was maintaining it, believe me if he saw String.Empty he would understand better what the code wants to do.

:stuck_out_tongue:

June 2007

AJ_Finch

My personal coding mantra:

No Code is Good Code

:wink:

June 2007

Bulletmagnet

“Source code is for humans to read, and only incidentally for machines to run.” - whoever said that (possibly Don Knuth^) knew a thing or two.

^ http://xkcd.com/c163.html

trousercuit : You want it in 17 lines? Does it have to fit in 80 columns ? (with apologies to Larry Wall)

June 2007

Reed

This is true, but it can become a bit of a problem when designing (or not designing) an SDK or library. When you try to make your own code simpler, you can end up making other people do more work and write more code.

I don’t know yet if there’s a solution to that conflict.

June 2007

Reed

Also, simple, easy to work with code does not neccesarily mean fewer lines or fewer bytes.

Reed

June 2007

John_Pirie

Not brevity, clarity. Clarity, clarity, clarity.

Write code whose purpose and operation are clear and readily understood from reading the code.

Brevity makes code clearer nearly always, but not always.

June 2007

Kirk

Some of us write code we will see over and over again in the years to come; some of us write code we will never see again. Some of us are on a very strict deadline; some of us have a bit more flexibility. Some of us have to write to strict coding standards; some of us don’t. “Brevity” means different things to each.

Code is communication. Some of us communicate with the compiler; some of us communicate with our future selves; some of us communicate with some unknown future maintainer. We do so because of the environments we are in.

When someone text messages CUL8R, they are being “brief.” To them, it is a recognizible element. When I get it, I have to parse it out… it is not immediately recognizible and, for me, it is not “brief” but tedious.

June 2007

Chubber

To be Good Code, it must be brief, beautiful and bountiful. In other words it must be as short as possible, well formed with good variable names (long enough to mean something, short enough to read) and structures, and do something useful.

One of the things that used to kill me was when people would always want to break code into the smallest possible procedures, classes or structures. Sure, your functions were 10 lines long. But to actually debug it I had to dereference 10 times and follow Alice down the rabbit hole to find out what was going on.

Like John P above me said, clear code is usually brief. Brief code is not always clear.

June 2007

Mickey

I have noticed that often Jeff writes from the viewpoint of an application developer (and often, very specific kinds of applications).
Indeed, when developing libraries the guiding principle is designing good interfaces, writing robust code, and caring about your user (and the library maintainer). The complexity of your code is simply not important as your clients (users of the library). And since library development and design is hard (it can be very hard), you have to trust that whoever maintains the library code is good enough. Again, clarity of code is really not on top of the list of priorities.

An interesting example is C++ STL. It is VERY easy to use. Incredibly easy, in fact, compared to the power it gives to the library user. But this comes at a price - the STL implementation is very complex.
Yet some of the STL implementations go for brevity, which makes the code even LESS clear.

I say this: always consider the various trade-offs when you write code (or design). Brevity sometimes make the code clearer, but as often as not, it does not. Sometimes clear code is simply not possible given the (time,performance,robustness,code,requirements) constraints.
Write code with your brain turned on. Design with forethought. Don’t over-engineer, or under-engineer. Don’t be tempted to assume that one rule is always true.

June 2007

NickB

I think this is very bad example using “” and String.Empty. Because essentially “” is a magic number of sorts, I am talking totally theoretical here, I know that “” is never going to change from representing a empty string, but what happens when developers start using “\n\r” instead of Environment.NewLine, not only does it cause a problem if you move to Mono it also requires a higher knowledge level to understand what “\n\r” means and you even have to remember what order it goes in.

It is good practice to get developers thinking that magic values such as “” and “\n\r” and any number is not the right way to code. Because if you tell them it is okay to use “” then why is it not okay to use 3.14F for PI instead of using Math.Pi?

It’s all about staying consistent and having the least amount of rules as possible, that is how you keep code simple across your organization.

Also by your same logic a developer should never use VB.NET because the language is way to verbose. I personally am a C# developer, but if a person is more productive in VB.NET and it meets the requirements for the project who am I to tell them they should use C# because it is less verbose.

June 2007

Narendra

Agree completely.
In fact, Thomas Kyte, the Oracle (specifically SQL) Guru keeps saying the same thing. One of the best examples that he gives for this is as follows:

A common requirement is update a record in table if it already exists, otherwise add a new record.
Logic as used by many:

SELECT COUNT(*)
INTO l_ctr
FROM MY_TABLE
WHERE key column = key column value;

If l_ctr = 0 THEN
INSERT INTO MY_TABLE (column list)
values (values);
Else
UPDATE MY_TABLE
SET columns = values
WHERE key column = key column value ;
End If;

Ideally, what should be used is a MERGE statement (in Oracle 9i and above and if using data from other table) orfollowing (in oracle 8i and below):

=================================================
UPDATE MY_TABLE
SET columns = values
WHERE key column = key column value ;

IF SQL%ROWCOUNT = 0 THEN
INSERT INTO MY_TABLE (column list)
values (values);

That SELECT is completely unnecessary.

June 2007

NickB

Roddy,

I like your boolean example, it is not because the developers want to be verbose it is just because developers don’t know boolean logic. I still hold my stance that the biggest hurdle in programing for the common developer is boolean logic.

June 2007

Kevin

Good post… the code example was a bit weak, tho. Like others, I too, favour the StringUtils.isBlank(str) approach.

June 2007

Bill161

You are missing an important distinction.

when you say “less code means less bugs”, we’re already assuming no spelling errors that the compiler can catch, right?

This implies that what you really mean is less unique operations, or less symbols is better.

I seriously doubt you’re saying that x=x+5 is better than increaseOutputBy(STD_INCREASE_RATE).

What you’re really saying is my oldest programming mantra–fully factored code is the only REAL measure of good code (if it does “the job” that is)

Honestly I don’t even care if it has errors, and is poorly documented if it’s fully factored, I can fix them easily. If it’s cut and past garbage that is fully documented and error-free (as though…), a small upgrade can take weeks of hair-pulling.

The new version of my little mantra is “DRY”, Don’t Repeat Yourself.

But get rid of the idea that a language is better because it has 30 ways to save a keystroke, it’s not keystrokes that are the problem by any stretch of the imagination.

Having the choice between:
func(a)
and
func a

is simply a lack of consistency, it doesn’t save a thing except 2 keystrokes–and as we’ve already seen, keystrokes aren’t a measure of anything.

Same with:
s="Bill was $(where)"
over
s="Bill was "+where

not a single bloody advantage (in fact, in some cases, it’s an EXTRA keystroke) but it clutters the language and adds to a significantly screwed up escaping system.

I’m also dealing with horrible code patterns like this now:

@user.attributes = valid_user_attributes.except :last_name
@user.should_not be_valid

Really cute concept, make the tests look readable. The problem is if the language hadn’t tempted them with the ability to leave off parens and override operators, it could have looked like this:

spec(“set user attributes to valid user attributes except last name”,
“user should not be valid”)

Neat, no random underline/dot patterns to get wrong and the code is even clearer. Simply because the library decided not to be tricky.

Your plug-in could even syntax check the above strings–or even use a new file type just for creating the tests. Everything would be easier, everything more straight-forward.

Wow, much easier. Data NEEDS to be data. Letting your language be so flexible that it tempts programmers to show of is just an invitation for disaster.

So stay away from “Brief” and start using “DRY”, because brief without DRY is far worse than DRY without brief.

Hell, in fact I would venture to wager (a LOT) that the optimum solution (out of a set of decent program samples that all accomplish the same thing in the same language) is actually going to be the MOST verbose solution that is still DRY.

June 2007

GregM

I gotta run, but I just wanted to comment on how we stopped focusing so much on machine optimization and more on human readability and maintainability. For many applications, our machines are fast enough. Also, we have come up with enough optimizers and caching systems to take care of stuff automatically for us, leaving us to write code conceptually, which finally liberates us from the silly machine dependency.

Now if only programming languages would get more intuitive, we’ll be on our way toward star trek :slight_smile:

June 2007

David

Less code means fewer bugs.

Each statement should do one and only one thing.

No subroutine / method / procedure / function should take up more than a page when printed out. If you can’t see it all at once, how are you going to understand what it does?

Comment extravagantly. One comment per five lines of code is a good average.

Small is beautiful. Keep it simple, stupid!

Test as you write. Five lines at a time is usually OK.

Never try to understand other people’s code, it’s always garbage. :wink: Rewrite it from scratch. It’s quicker and you know it works.

The best programs are written when you have nothing but a pencil and paper to hand.

June 2007

Steve

Wow, programmers are nothing if not pedantic. The example is meaningless and unimportant. Try reading the article again if you think it’s in anyway about proper empty string handling. Or I can highlight the most important sentence for you:

“Every new line of code you willingly bring into the world is code that has to be debugged, code that has to be read and understood, code that has to be supported.”

June 2007

EricL

Aaron asks above whether LINQ queries may be explicitly typed. Provided that the return type of the query does not include an anonymous type, then sure, why not? “var” is only necessary when the type has no name; if the type has a name then using “var” is merely a convenience.

Note also that you could write your routine as an extension method:
public static class MyUsefulExtensions{
static IEnumerableint Square(this IEnumerableint list) {
return from x in list select x*x;
}
}

IEnumerableint squares = mylist.Square();

which is a syntactic sugar for

IEnumerableint squares = MyUsefulExtensions.Square(mylist);

However, in such a simple case one probably would not write the method to return a query. I would be more inclined to write this as

public static class MyUsefulExtensions{
static IEnumerableint Square(this IEnumerableint list) {
foreach(int x in list) yield x*x;
}
}

Either way, it does basically the same thing.

June 2007

Jack52

I agree with you, but at the same time it makes me happy to include things in my code that do absolutely nothing…I know this sounds cruel and unusual but I somtimes like to think of all my successors looking at my code and saying WTF?

June 2007

EricL

Well that is very irritating.

Your comment system stripped out all of the IEnumerable ANGLE BRACKET HERE int ANGLE BRACKET HERE bits in my comment. Makes it hard to post comments about generic types, no?

All of those IEnumerables above should be “of int”.

June 2007

EricL

Well that is very irritating.

Your comment system stripped out all of the IEnumerable ANGLE BRACKET HERE int ANGLE BRACKET HERE bits in my comment. Makes it hard to post comments about generic types, no?

All of those IEnumerables above should be “of int”.

June 2007

Darren_Kopp

I always do string s = string.Empty; because people seem to think that if string s = “”; that the = “” isn’t really important and will delete it.

also, string s = string.Empty is a bit more readable in my opinion. and it doesn’t take much longer to do. it’s st + . + em + enter. that puts in string.Empty. hoooray.

June 2007

Rob_K

I want to agree, but your example tastes of premature optimization to me. I think the number one factor, the very first concern must be clarity. If your code is not clear, it’s harder to understand, and if it’s harder to understand, it’s harder to know that it is correct.

Clarity first, foremost, and above all else.

June 2007

BobbieT

Less code comes from higher level languages, and one that’s suited to the task at hand.

That’s why C++ and Java projects take forever. So much code must be written.

June 2007

PaulP

I’ve been programming for thirty years and I’m still amazed at the discussion of this age old thought about programming. At first, I thought everyone gets what Jeff is saying. I’ve heard it said many times. The comments don’t lie, though.

The answer - stop defending your technique, lose your ego, keep “Code Complete” next to you when you’re writing and read it, read real production code as much as possible, sharpen your technique, simplify, simplify, simplify …

June 2007

Dieter_be

Hey Jeff. You made some good points. I’m gonna think some more about this.

I love your blog

June 2007

SeanP

I want to second the suggestion about Googling for Error Messages, I’ve often found it far nicer than what the MSDN standard output can be. If you DO write the article, contact me via the web site, I have a hilarious “Get Fuzzy” comic that would apply.

I find it funny how many people immediately look at the code and provide the “alternate” solution as opposed to looking at the concept itself. I’ve become a BIG fan of the maintainability camp over the last couple years and I think the “proper” solution is one that is efficient now and understandable later. You can use the if s == “” statement, but there better be something else to explain why this is happening, or maintenance is a bear later.

You may be using an empty string to indicate that a parameter wasn’t specified, and I may update it to change empty string to “Nothing”, thinking it would be more efficient and I’ve just ruined the app.

June 2007

Jim_P

I came across a quote a few months back that sums this blog up:

You have a choice: fast, good, cheap.
Pick any two.

June 2007

Jethro1

A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away.


Antoine de Saint-Exupery

June 2007

Crimson

Clarity, not brevity is the thing that should be put on a pedestal. Brief code isn’t necessarily clearer code. Sometimes a terse line of code needs to be split over several lines so that the engineer can clearly see what’s happening. Based on your view though, this is bad because there is more code to “break”. I disagree.

That said while I agree with the spirit of your argument, but you misinterpreted Wil Shipley’s blog. He was talking about adding unnecessary complexity and functionality before it was really needed, not using the most concise representations available to the language.

June 2007

Steve_Riley

The main issue is simplifying the problem domain. Programmers who have less insight have a tendency to think everything is a special case and spew out code to deal with all of these special cases. Programmers with insight can factor out all of the common elements. It isn’t uncommon to see code that can be rewritten in the same language, be more robust and be 1/10 the size.

There is a tradeoff point though. Code that is more powerful and concise often hits a point where it is difficult for many programmers to grok. If all programmers were top notch then lisp variants would be all the rage. So it all depends on your team. If they are top notch use recursion, lambda functions and all the rest. But in some shops you really have to watch the power/clever vs. lengthy/weak/simple trade off. Good code is (unfortunately) like any other kind of writing. You have to write it to the skill level of your audience.

June 2007

Gregory

I honestly don’t see what’s so hard to code cleanly and clearly. For most software, I mean. It’s just tedious. Just follow what the actual concepts are, by definition, and KNOW where you are sacrificing good design for optimization.

OOP and coding exactly to the definitions of things will always get you the correct results. Because whenever you get a problem, it will correspond to a real world problem, and then you document how you decided to fix it. If the problem is optimizing something, THEN you have to make some assumptions / hacks to make things work faster. Document them, because they are going to limit your program.

But given enough time and no optimizations, your code should be awesome.

June 2007

Rafajafar

“Make everything as simple as possible, but not simpler.” - Albert Einstein.

June 2007

GPG

I agree with less code == less bugs … for the most part. Unless that bit of code that you left out introduces other bugs - this I have seen.

One point of contention … code does not rot … had a clueless manager one time that said the same thing. Rot implies that the code changes randomly … it does not, heuristic programming aside.

Code, unless it is dynamically generated, is static unless someone changes it. The compiled result might degradate, due to the media that it is stored on, but the code itself does not “rot”. It might get mangled, broken or munged but it does not rot.

June 2007

TheophileE

As someone who’s had to do a LOT of maintenance over the years, I strongly disagree with this.

It’s true that you should keep the COMPLEXITY of the system to a minimum. But using String.Empty does not increase the complexity of the code at all: it’s the same decision point either way.

Keeping the code “small” does not mean sacrificing maintainability by using meaningless abbreviated variable and function names, for instance.

In terms of maintainability, String.Empty rules out two distinct classes of bug.

  1. “Fill in the gaps later”. A lot of programmers start out peppering their code with “” and fill in the contents later. Yes, you think you’re too smart to do that. Newsflash: not everyone who alters your code is going to be as smart as you or do things your way.

Using String.Empty tells the suspicious maintenance programmer, “yes, I really meant that to be an empty string”. And an experienced maintenance programmer is always suspicious.

  1. The difference between “” and " ". If you’re in a hurry, it’s easy to overlook the difference between those two statements, and that’s another source of bugs.

Why do I get the impression that a lot of people giving advice on how to write maintainable code have never had to actually maintain old code? If you haven’t accumulated several years maintenance experience, in several different companies, with code that’s been through several different generations of programmers; you probably don’t know what the real sources of confusion are.

June 2007

Ian

While a good article your example of String.Empty is plain wrong but not for the reason you think. Ignoring the correct answer of IsNullOrEmpty as pointed out by others, you should always use if(s == string.Empty), again pointed out by others, as the intention is clearer and less jarring to the programmer reading through it afterwards. Which is who you really code is for. When I see people comparing writing == “” I know they haven’t written code on a big project and certainly haven’t maintained that code :wink:

June 2007

MithunJ

Yes, the sight of huge blocks of code does make me sick but at times brevity leads to the creation of a smaller but illegible block code which is ridiculously hard to debug or expand upon.

Hence at times, writing large but organized code where every entity in the code is meaningfully part of an underlying theme is much better than a single block of unintelligible code.

June 2007

StephanS

if (s == String.Empty)
if (s == “”)

The first is better, because “As a software developer, you are your own worst enemy.” Realize that. So everything which helps you keeping your stupidity out of the code you write is a good thing.

What about the typo:

if (s == " ")

What about if during the lifecycle of the programm the definition of empty changes to whitespace? As people mentioned above, best would be

if (s.isEmpty())

or in some languages which prevent null dereferencing (like Groovy)

if (s?.isEmpty())

or use a language with null objects. Beside all that the complexity of the code (CC) is the same for both examples. And modern reading recognition studies hint that people do not read character by character, but by reading patterns and anchors. So from reading and parsing speed probably both are the same too.

“As a software developer, you are your own worst enemy.”

June 2007

AndyW

I feel that it would be better to have a definition of whitespace/null/empty that is consistent through all the code. Then it is easy to check for consistency. And you only have to remember one method.

Besides if you want to be fast set a standard then use it.

Anyone but me have to rework code after a code-review just to be consistent? Or do you guys even have code-reviews anymore?

June 2007

oftencloudy

“If you love writing code-- really, truly love to write code-- you’ll love it enough to write as little of it as possible.”

Is this along the lines of “if you love something, let it go”?

June 2007

AndreasK

The String.Empty reminds me heavily on VxWorks EOS (End of String). They want ‘while (*x != EOS)’ instead of (*x != 0) or simply (*x). Now, how can I even trust them to define EOS as 0, and how pointless is that?

And after stumbling over enum { TRUE = 1, FALSE = 2 } elsewhere, you are going to be careful with assumptions.

And finally the IsEmptyOrNull crowd probably really wants My.IsInvalid instead. If you don’t accept empty strings, you probably won’t want to accept strings consisting only of whitespace either. And then there was the input validator that thought a city name must have at least four characters. Well, not at 10E 4824N.

June 2007

Roddy

My favourite verbose horror is code that doesn’t understand booleans.

eg.

if (a==b)
thesame = true;
else
thesame = false;

…and…

if (thesame == true)

Hopefully I don’t need to say how I’d like those written!

June 2007

Brad

Couldn’t agree more with the content; couldn’t disagree more with the sample. String.Empty isn’t more readable to the compiler - it’s more readable to the human. A non-programmer could understand this (assuming he/she was explained what a “string” is).
Besides that, to me this reinforces another code minimization technique: look in the framework. Some other programmer may see this and think "I didn’t know there was a String.Empty in the framework, what else is there that I don’t know about?).

June 2007

Mickey

You (and I guess the people you are quoting) are looking at the problem at the wrong level entirely.
The problem is not bloated code, it is bloated design. Basically, it is over engineering.

Code Brevity is a poor replacement for application of the KISS engineering principle (Keep It Simple, Stupid). Should I declare 4 variables with a single line? How is that any better than using 4 lines?

Also I agree with S.Empty() rather than (S == “”). It is more bug prone and harder to maintain. I could also make the case that it the comparison is in fact more complex code, a binary operation with two operands.

I would also like to note that under-engineering is also a very big issue. If you don’t look ahead, your design (or code) is likely to bite you later.

Wil Shipley’s advice “Start with brevity. Increase the other dimensions as required by testing” is just another way of saying “Don’t exercise forethought! Run along and code. We can always fix it later.”

June 2007

serge

Hi Jeff, nice piece of article.

Actually I’m not a big fan of the Zen attitude, and your conclusion, though ironic, seems a bit void to me :wink:

Thus I suggest using “necessity” instead of “brevity”. By “necessity” I mean: only add statements that are strictly necessary to prove the code is working.
And because I think “necessity” can take many forms, you can make it more or less “explicit” as a trade-off. By that I mean to make the circumstances under which the code works more or less explicit.
Why I do find interesting to challenge your view? Because it focuses on making the code working (not just nice), and integrating the assumption into it (not just readable).
The full post is here: http://lecoupdansloeil.blogspot.com/2007/06/coding-horror-best-code-is-no-code-at.html

Thanks!

June 2007

Cornie

I agree 100% with Jeff. Less is by far better. I am Delphi programmer and work on the following basis.

  1. Get the job done. (a / b = …) [10% of the code] (Customer is 75% happy.)
  2. Ensure user input is correct. (b is not zero, null, 0 or what ever zero is not allowed.) [20 % of code.] Customer is 90% happy.
  3. Add a progress bar [3% of Code.] Customer is 100% happy.
  4. Speed the whole process up [20% of the code, as I have to write custom code for this procedure] (Customer is still 100% happy, although I think I am very clever saving him 10 seconds every day.)
  5. And if I was M$ I would have design a cool user interface that would have slowed down everything by a factor of 10. [47% of Code] (Customer 50% happy, but me daughter of 14 thinks it looks cool!)

The fact of the matter is that 33% of the code has done the job 100%!

June 2007

rabidw

Ya missed one:

Understandability.

This is probably the most underrated and yet important of these so called ‘dimensions’ of software development.

I would much rather write a verbose understandable piece of code vs a tight super efficient and impossible to figure out later tribute to my ego.

Don’t get me wrong, there are times when tighter is better (like when you reach home plate) but for most of us we are not writing time critical routines that are controlling the interceptor missile during the last 30 milliseconds.

June 2007

Kyralessa

I have to stand with TheophileEscargot (and numerous others) on this. String.Empty illustrates purpose, whereas “” could be a typo.

You know the rule where you’re bound to make a grammatical or spelling error when you post correcting someone’s grammar or spelling? Perhaps this is an instance of a similar rule, where when you want to make a wide-ranging and perfectly valid (if obvious) point, you inevitably end up picking a non-obvious, borderline example that a lot of people will disagree with.

In other recent news, after the drubbing his book got here, Charles Petzold has decided to make himself feel better in the time-honored manner every child knows: Distract attention from yourself by picking on somebody else…

http://www.charlespetzold.com/blog/2007/05/310543.html

June 2007

codinghorror

I think the example given here has proved the point which this column wanted to prove. You see there are at least 10 entries discussing the pros and cons of those 2 (just two) lines of code. In real life, this is the time wasted and it did happen here also

Yes, I now regret including this minor example. It is instructive to see how even the tiniest of details can become a point of contention… one programmer’s brevity is another programmer’s idea of sloppy code.

Maybe you have to go the dynamic language route: that’s not sloppy code, I just (added custom language keywords | redefined existing language keywords) to make the code more succint. :stuck_out_tongue:

June 2007

Ergo

Jeff,

With all this talk about which languages are best to use and code being quoted, I thought I was reading your fizz buzz article!!! They quote their code and completely forget the topic :slight_smile:

http://www.codinghorror.com/blog/archives/000804.html

June 2007

Dygear

That’s one of the reasons why I love the action reaction part of SmallC (Now known as PAWN). You make the event function handler and it runs your code once that happens.

June 2007

Chepech

I have never found a coder which doesn’t complain about someone else code, this means that either we have the tendency to be extremly perfectionists with other’s code or that simply we are petulant ass holes that don’t realize that as in art appreciation there is no such thing as the omipowerful voice of all reason and true. There is no such thing as perfect code, PERIOD. Great code depends a lot on who you ask. For the people who pays for it its the cheap one that works fine and gets done in a blink. For developers is the one that is clear short and COMMENTED. For me it depends on the situation… but I never loose pragmatism and self improvement of the target.

Just a humble opinion.

June 2007

NevinL

You are asking the wrong question.

Instead of s== “” vs. String.Empty, you should be asking why the empty string needs to be special cased in the first place.

If you want smaller, more maintainable code, get rid of the unnecessary special cases.

June 2007

scotto

Perhaps a better example would have been:

if (false == flag)

if (!flag)

People can probably still find a reason to complain but it’s a much more straightforward example of good, brief code.

June 2007

JohnnyE

This is easy. You should always use String.Empty, and constants in general, because it’s good practice.

I worked at lendingtree.com for a few years. One day one of the business folks came over and asked us if we could change it from 4 offers to 5. We all started laughing. You know why? Because the morons that had started writing the code did things like

If OTF = 4 and Blah 4 then

No way to translate. Please, for the love of god. Don’t write short code. Write good code. Someone else might have to maintain your crap some day.

June 2007

martin7

Perceivability - this dimension is missing
Code is more read than written and the stack size of the human brain is about 3.

if (s == String.Empty)
if (s == “”)

It seems obvious to me that the latter case is better because it’s
just plain smaller. And yet I’m virtually guaranteed to encounter
developers who will fight me, almost literally to the death, because
they’re absolutely convinced that the verbosity of String.Empty is
somehow friendlier to the compiler. As if I care about that. As if
anyone cared about that

Bad example, bad explained, personal believe stated as objective fact.

June 2007

ChrisM

I’m all for simplicity and maintainability.

if (s == String.Empty)
if (s == “”)

But like the first comment says (GuyNamedNate), String.Empty just seems like the right thing to use even though “” is easier to type.

if (false == flag)
if (!flag)

Its interesting but as the years have gone by I’ve revert from (!flag) to (flag == false). Using (!flag) is again easier but explicitly showing (flag == false) just makes for more readable code, that little ! could so easily be missed whilst flicking through someone else’s code.

I know its stupid but it really annoys me when I have to make a change to code and the original developer has left out the braces, although I’m sure they were just simplifying the code:

Example: If (flag) return var;

I can’t help it but I have to add the braces in…

June 2007

ALeX29

In Python, you just

if s:

empty strings evaluate as False. Simple and readable!

June 2007

OnofP

Couldn’t agree with your example, because you are in a framework and don’t know if tomorrow empty strings will be represented as “\^*0” or as 0xbb or MSDN_Useful_Content.
Indeed, I program mostly in C and in order to avoid lamers to understand my code i prefer:
if(!*pszStr)

When in C++ i use STL so:
if(! string.lenght())
STL are better than any other framework: no null pointers, no bagous arrays, no 100-cpu-clocks for an integer comparison.

Bye

June 2007

AlexThunder

The source of sickness is a patient. To be a most succesfull practical doctor one must reduce the number of patients he has. Best doctor is the one who doesn’t have any.
No patients - no illnesses.
No code - no debugging, no problems, no slipless nights, no nightmares.

All this article sounds like horse-rider talk about cars and all machinery. You don’t like cars - ride your horse and don’t complain. You don’t like programming and coding - do cleaning, cooking, babysitting, you name it. Just don’t tell me that any problem can be solved in three lines of code. I simply don’t believe it and I can give you examples if you’d like to see ones. Programming naturally IS solving problems work. If you are not happy to deal with problems - programming is not your area.