Why not become a lifetime supporting member of the site with a one-time donation of any amount? Your donation entitles you to a ton of additional benefits, including access to exclusive discounts and downloads, the ability to enter monthly free software drawings, and a single non-expiring license key for all of our programs.

You must sign up here before you can post and access some areas of the site. Registration is totally free and confidential.

Tonight a highly subjective question was proposed concerning "What Beautiful Code should be." There are a lot of important questions and while I understand this might be a very debatable topic, let's take some time to talk about this... Why? you might ask. Well, because it's important... Take a look at some of the following points made by our very own mouser, Gothi[c] and Deozaan:

1. It is better to have 20 lines of understandable clear simple code than 4 lines of complexity. - Mouser2. The real question is does it make any non-negligable difference when it's all compiled down to bytecode anyway? If so, it probably needs to be evaluated for each programming language. - Deozaan3. If it uses more memory, so what? Premature optimization is the root of all evil. Lets not optimize that until a problem is created by being too organized, which is near impossible. - CodeByter4. Would you rather have a program use 100k extra memory or have the same program crash more often because its code is hard to understand? - mouser5. If the program needs to read millions of pieces of data, then 1ms of delay can add up. - Deozaan6. There's a balance between clear code and complex code with less lines. Just clarity at the cost of crazy insane slowdown would be silly. - Gothi[c]7. Even when code is slower, you have to ask yourself, is it happening in a place that matters. There are very very few cases where it is better to have ugly short code than longer clearer code. - Mouser8. We shouldn't strive to write longer code but rather to write code that is easy to understand. - Mouser9. The goal should be: efficient easy to understand, short if possible, code. - Gothi[c]

I'm not trying to knock the book beautiful code, but commenting on that list by codebyter from the book, i thought it conveyed the wrong focus. It's focused much too much on brevity, and much too little on explanatory power.

One should not write source code like one writes poetry and literature. One should write source code as if writing a textbook -- focusing on explanatory power and clarity.

I guess i can sum up my view like this:

One should endeavor to write code which is most of all: clear and easy to read and understand.

I think one is almost always better spending 20 lines writing something in a way that is crystal clear, than accomplishing the same thing in 2 lines of code that requires careful study. The more "clever" those 2 lines of code are, the worse.

Writing code is different from poetry and literature in that the goal should not be cleverness and coming up with some surprising and unusually short snippet of code that accomplishes something.

Even in those very rare rare cases where the longer, clearer code uses more memory or takes more cpu cycles, and in which that speed/cpu difference actually impacts usability (truly rare cases), i still believe it's best to write it the clear way first, then come back and refactor later for efficiency if you must.

Or you might even be able to sum it up by saying:Write code as if you're goal was to produce something that was self-explanatory, that could teach a new maintainer how the system works and make it as easy as possible for them to take over from you. And note that the primary motivation for doing this is *not* because you might have to turn over control of the code at some point, but that this approach makes it easier for *you* to maintain the code going forward and makes it easier for you to debug, which is what you're going to be spending most of your time doing whether you like it or not.

As a non-coder, my end sees good code stemming from good design. It's easy to over-design. To start out by saying, "Hmm, maybe somebody would find this useful, that useful, and also that, that, and that over there" will lead to future frustration. Start from what you know people must have, and then try to make that set smaller. When you can make it no smaller, you've reached a nice [starting] place with your project.

I agree with mouser. And I think it especially applies to beginners to programming. As you're learning how to program (or a specific language) it's best to be clear so you can understand what it is you're doing when you come back from a week vacation than to try to be clever at the moment and have to spend 15 minutes trying to figure out how a relatively simple function works.

In my own programming projects, I've found that I tend to try to be lazy or clever and I'm almost always successful if I spend enough time thinking about it. But then when I come back to it later I have to spend just as much time figuring out how it really works, even if I've commented it in a way I thought was clear at the time.

Also, I've often found myself spending hours trying to think of a clever way to accomplish something and then in the end I use the idea I had at the very beginning but decided it was too much work and there had to be a more clever simpler way. And usually in these situations I find that what I thought was the "harder" way is actually completed and working much sooner than those hours I spent coming up with and testing new tricks to accomplish the task.

Finally, I'll just point out that your Beautiful Code blog entry seems to be making the assumption that simple code is equal to less code is equal to shorter code. I think that the original idea is perverted along the lines from Simple to Short, much like a game of Telephonew. The original idea is "Simple code is beautiful code" and my interpretation of that is that simpler code is doing less things per line, resulting in shorter commands, but longer code.

Have you ever tried to understand source code you've never worked on? It can be very overwhelming. Code you can understand is indeed beautiful.

So if you simplify your code you will likely end up with more lines of code, but who doesn't like to brag about how many thousands of lines their code is? It makes a nice bullet point to show off how awesome your program is. Now, as with most things, there should be moderation. You shouldn't be a total zealot for only one simple thing per line of code always and forever. There is definitely a balance. The idea is to write your code simply and beautifully without going to extremes.

If it's cryptic the cook (coder) won't understand it and the meal will come out a disaster at some point in time.

Say "peas" when you mean "peas", "carrots" when you mean "carrots", and "eggs" when you mean "eggs". (use good variable names)Substituting with x, y, and z will not do. How does it make any sense to refer to an "egg" in a recipe as "z"?

It is usually better to break it down into step by step instructions instead of having one giant mega do-it-all-in-one-step (this agrees with mouser)

Plan for getting amnesia (you will) by leaving notes to yourself (comments) to explain why you used what you used, and did what you did. If something doesn't work and you have fixed it, leave a note to yourself not to try that again. Example in recipe talk: soy milk makes instant pudding runny, use real milk only.

The end result is a recipe (program) that you will be able to undersatand like a master chef (master coder).

And if/when the time comes that you have to pass the recipe (code) down to the next generation (coder), they will be able to understand it too.

Now, if what I said doesn't make sense, ask your grandmother to explain it. She is probably a much better hacker than you give her credit for.

3. If it uses more memory, so what? Premature optimization is the root of all evil. Lets not optimize that until a problem is created by being too organized, which is near impossible. - CodeByter

Premature pessimization can be just as bad, though - a mix of sloppy design and sloppy code can sometimes lead to requiring more a less a rewrite to fix performance problems later on. Don't obsess with needles micro-optimizations, but be careful about using "premature optimization is the root of all evil" as a lazy blanket statement excuse for writing crap code as well

I don't know, but outside the extremes like perl one-liners and c++ overloaded operator gobbledygook I find less code enormously easier to read.

For example I'd extremely limit introducing an intermediate variable when the return of a function is needed only once and can be written inline. This has nothing to do with efficiency, a compiler would probably make the same code anyway. But yet another variable, even clearly named, just complicates the code.

Off hand now other examples are hard to think of, but ultimately I would say that I virtually never come across case where 2 lines is actually less legible than 20. Use good names but otherwise be a succinct as possible I'd say is the best rule of thumb.

« Last Edit: February 19, 2009, 04:51:23 AM by EÃ³in »

Logged

Interviewer: Is there anything you don't like?Bjarne Stroustrup: Marketing hype as a substitute for technical argument. Thoughtless adherence to dogma. Pride in ignorance.

Maybe I missed it somewhere, but I also think that formatting adds a lot. You can tell a lot about where you are in a program from indentation and other stylistic matters that the compiler doesn't care about, but makes the programmers life a bit simpler. Simple-minded I know, but so am I.

I find it beautiful to create such complicate code (for maximum optimising) that I need after some time hours to understand what I did there how and why. But hey, IÂ´m not a pervert, I only follow my animal instincts!The strange reason could be hidden deep in the social role behaviour of men: The mystery of unknown secrets makes also women more attractive and itÂ´s a lot of fun to reveal them. After a while out of sight they regain this cloak of mystery again.

I'm no coder, but I always try and stick to this simple rule - always code for the lowest common denominator (usually me...)

This applies equally to the use (how many of us have found a piece of software that could be the answer to all our prayers, if only we could just work out how to use it...) AND maintenance of your code (most of the posts above have commented about having to spend considerable time relearning code in order to make a change)

Brevity is always good, but if the benefits are negligible it's always better to write simple and clear code

« Last Edit: February 19, 2009, 11:14:10 PM by Target »

Logged

"Look wise, say nothing, and grunt. Speech was given to conceal thought" - Sir William Osler

To me, beautiful code is more about formatting than length/brevity. Improperly indented code is awful. Code with the {{}{}{}}{{}{}}{} syndrome is disgusting (ala tcl). Though I must admit, code like Perl, where you can do the most outrageous ridiculous things on one line is truly fascinating and beautiful to me.

Concerning complicated code: we have a guideline that says if one thinks he needs to explain in a code comment what a certain piece of code is doing, he should consider rewriting the respective code to make it more self explanatory. For example, often refactoring a piece of code into its own function and giving that function a suitable name makes a comment obsolete. Obviously, this way functions make a one-liner out of a 20-line piece of code, i.e. it's useful to make a function even if that function is called only once.

While I think/agree that it is usually preferrable to write something 'simpler' (which often results in more lines of code) contrary to more clever (which often results in complicated one line statements) I tend to start making 'exceptions' to that rule myself. The questions that come up are: should one use 'advanced' language features of a programming language? Which features are considered to be advanced: the complicated ones?, or the seldom used ones?, or the new ones?, or even just the non-trivial (but still well-established) ones? How much knowledge about a programming language can you expect your collegues to have? How much can you expect them to learn?

My background is C++ programming. It's certainly not the easiest programming language to use or learn. And it's evolving. In an internal training, I was introducing my collegues to std::tr1::bind and std::tr1::mem_fn which will be part of the new C++0x standard (but are already available to us when using MSVC 2008 SP1 or the boost C++ library).

Let me show you an example to demonstrate my point:

I would expect a novice C++ programmer to understand the following piece of code. Assume _controls to be of type std::vector, which basically abstracts an array and which allows access to the items in the array via array[index].

Knowing about iterators is not enough any more. Now you need to know what for_each does and you need to know what bind does.

Everyone with a bit of programming experience understands what the first code example does. Some people claim the one-line for_each statement to be safer (or more efficient) but I'm not sure this is enough reason to prefer it over one of the hand-written loops. While I today prefer this kind of code, it's hard for me to explain why.

If someone wants to share her/his opinion, I would be very interested!

phitsc, to me the question of what knowledge of a language you can expect from others is a separate issue. Though of course a very important one in a team situation.

In your example the decision I'd be trying to make is between you third example or a similar 2 line version where the result of the bind is stored in a tr1::function. It's the trade off between the evil of introducing a redundant variable versus the evil that the single line version is too long.

Logged

Interviewer: Is there anything you don't like?Bjarne Stroustrup: Marketing hype as a substitute for technical argument. Thoughtless adherence to dogma. Pride in ignorance.

In your example the decision I'd be trying to make is between you third example or a similar 2 line version where the result of the bind is stored in a tr1::function. It's the trade off between the evil of introducing a redundant variable versus the evil that the single line version is too long.

I agree, we often do this (as you can see in my 2nd code example). Temporary variables are not only good to shorten lines and make complicated looking code look less complicated, they can also make it easier to debug. On the other hand, we get ever wider screens

This is one of the reasons I indent only 2 spaces and try to have shorter variable names -- fitting things in 80 cols is tough sometimes...

I'm thinking of experimenting w/ using CJK characters for identifiers (at least you can do this in some programming languages) -- meaningful names (at least to those who can read them) that don't take up so much space! I guess it's not so likely to catch on...may be the following will some day:

Wide lines take longer to read than short ones - you spend too much time re-sync'ing when you progress to the next line. The additional vertical space that widescreen monitors offer is better used on stuff like IDE toolbars, imo.

On the other hand, too short identifiers make code cryptic to read, and this is a problem you often see in *u*x source. On the other end of the spectrum we have Windows' VeryLongFunctionNamesThatAreSometimesOverTheTop(), along with sometimes insanely long argument lists - that's not win either.

If you need two-space tab, you should probably refactor your code

Non-english characters (heck, even language) in source code? Don't even get me started