Thursday, 5 February 2009

When did we all get so lazy?

There seems to be a movement towards writing less code. I see it all the time.

  1. You have C and C# evangelists who can't stand Pascal because they can do in two key strokes, what Pascal does in nine ({ and } as opposed to begin and end;) This one's a personal preference issue. Personally I find begin and end 100 times more readable, but I also understand that others may prefer their curly braces.
  2. In my post about garbage collection, some of the commentators reminded me that if you use Delphi, because it doesn't have garbage collection, you have to write 40% more code (all those silly try..finally clauses). Again, you may have valid reasons to want garbage collection, and I respect those reasons. But don;t tell me writing less code is a good reason.
  3. The push towards functional programming is another one. I'm told that using a functional programming language for certain problems would result in me writing a lot less code. Look Ma, I wrote all that code in one line! I may be a bit harsh here, as some of the functional constructs are really elegant, but what I'm getting at is that use something by all means if it results in your code being more readable, and not because it results in a few less lines.
  4. Pascal requires an interface and an implementation section. You declare a class twice. It must be bad right? Like I've said before, for me, a Pascal class is immediately readable. The interface has no clutter. To achieve the same thing with say, a C# class you need code folding.

I could go on and on. I think the theory goes that if you can type, say 70 wpm, and that you can't physically type faster than that, then the only way to churn applications out faster is to use languages and constructs that need less typing. The theory implies that if you are writing 40% less code than I am, (and we both type at the same speed), then you're producing 40% more work than I am. What the theory conveniently ignores is that I may think 40% faster than you. I'm not saying that writing less code is a bad thing. I will always write less code if I can, but never at the expense of clarity. I will add begin and end where the compiler doesn't need them if I think it makes the code less ambiguous. I'll not use the with construct , and retype the object or record instance each and every time, if I think the code is more readable for it (it always is). The important thing to remember is the speed a developer can write good maintainable code is rarely due to the number of characters he/she can churn out. A lot of it is to do with the thought that goes into producing the code, when the hands are no where near the keyboard. It's to do with the cost of maintenance of that code. This all reminds me of those C competitions where C enthusiasts would vie to write the shortest piece of code that actually does something. It doesn't matter that you had to sit down with pen and paper for a few hours to figure out what his little program did. Aim for clarity and eliminate ambiguity. If that means you end up writing a bit more code, so be it, in the long run you'll actually save time.


Anonymous said...

Code is read many more times than written. Having to read less code is usually good. This implies writing less code / refactoring to less code is a good thing as well.

Richard K

Anonymous said...

Interesting post.

I'd disagree with Richard: I think because code is read far more than written, it should be written clearly, and that often means longer (as with your example of writing begin/end when they're not strictly necessary, etc.)

If you're reading code, what's slower - reading a few extra words or lines, or pausing to figure out what the code means?

Xepol said...

I always use begin/end, if I omit them, I was being lazy and I do my damndest to track down and fix it.

I found out a long, long time ago that it was easier to just always type them than to try find out why

if condition then

wasn't working right (it can even be pretty hard to find in a lot of cases).

I do have one case where I find WITH is both useful and makes the code more readable : TCANVAS. I can't think of any other cases I have ever run across.

Anonymous said...

I have to agree with Richard. It is not about the typing (the ide fixes that problem), it is about the maintenance. Everything else being equal, it is easier to maintain 60 lines of code than 100 lines of code.

There is some inherent redundancy between the interface section and the implementation section. It isn't a big deal when you are first writing the code (the ide makes it easy). However keeping the 2 sections in sync while maintaining the code is one more task that takes a finite amount of time.

I have written a lot of Delphi code and think Delphi is a wonderful product. I find it to be very readable. The interface section serves to document the implementation, so it does have value.

That said, the language trends of today are to reduce redundancy and minimize boilerplate and clutter. I think that Delphi needs to move in that direction as well.

Anonymous said...

It is interesting since I have over 20 years of programming experience and I started with both the line-numbering BASIC version and Pascal. I've gone from procedural programming though modular programming to object-oriented programming and nowadays I do mostly C# and Delphi/Win32.
One of the things I've learned is to not focus on the development tools. Each tool, each language, has it's own strengths and weaknesses. What is important is reaching your goal. Remembering what you're trying to do that needs the code you're writing. And I just notice that most people tend to be too focused on using the proper techniques, forgetting all about the goal. Even readability is just not a requirement if that makes it more difficult to reach your goal...

However, I do disagree on one major point. Writing less code is far more efficient. Basically, every line of code will increase the chance of adding more bugs. So writing 5 lines of code will generate less buggy code than writing 50 lines of code. Of course, if those 5 lines of code rely on another unit with 250 lines of code, it does become more risky again. Basically, you'd have to weight the risks every time. Will your few lines of code be using other code that's well-tested and (almost) bug-free? If so, write less code!

Another point is of course the interface/implementation division that Pascal uses. However, it has always amazed me that most object-oriented programming languages still don't provide a better visual tool for adding methods to a class. It would be so great when you could use UML to define your objects and add links between them and then write additional code for the method logic. I still don't know why we're still relying on flat text files to write code but then again, there's no good alternative at this moment.
With visible objects in some diagram-style, it would be real interesting to design new applications and will also improve the focus on a better OO design.

There are -of course- some attempts made to design such languages. Attempts to e.g. use UML with additional code that would compile directly to new applications. It hasn't been very successful so far. Mostly because people aren't too happy to learn new programming languages. (Besides, what syntax would the UML code be based upon? Basic? C? Or Pascal?)

Anonymous said...

Source code is read more times than it is written (I copied that from the first comment because it is true and important!), and in my view, any programming language that doesn't separate interface from implementation, has a serious flaw.

In order to improve readability, you can start counting:

* How many lines of code does the implementation section have (fewer means better)

* How many lookups does it take to read code (zero is good)

But when it comes to amount of code, there are many programmers out there today, who don't write more than 20WPM.

It seems to me, that you have a serious problem in your programming team: Work satisfaction. The problem is not the syntax. Your colleagues may complain about syntax, but their real problem is something else. It's like children: They may ask for something stupid just to get attention. Why? Because attention makes children happy.

So you need to refocus your team on the business instead of the programming, and you need to ensure that they think they're doing meaningful stuff. Once you do that, most of the team will be happy, and syntax is no longer an issue.

I have only met 2 other companies in my business, who made really, really impressive products. They were both using Delphi/Win32. Is this a coincidence? I have no idea, seriously.

Anonymous said...

In my post about garbage collection, some of the commentators reminded me that if you use Delphi, because it doesn't have garbage collection, you have to write 40% more code (all those silly try..finally clauses).

True, readable code is better than onliners.

Anonymous said...

Amen to that.

Of course one can argue that less to type also means less to read and that inherently makes it clearer to the reader. Those who say that, I usually point to the obfuscated Perl contest. ;-)

Patrick said...

@Richard King : Having to read less code doesn't necessarily mean it's easier to understand.

Actually, this was kind of the argument : Make your code better to understand, even if it takes more characters/words/whitespace/lines/whatever.

An example is in place I guess; In our shop, we prepend a {var} comment wherever we supply a value to a 'var' function-argument. This might mean more code, but with this construct, we don't have to look up if the called method could change the supplied variable!

Another this that helps understanding code, is when it's using a consistent style.
The actual style itself can be whatever you prefer, but be consistent with it in your entire team! (Generally speaking, using a style that matches the Delphi RTL and VCL code is a good starting point.)

And let me stress this again : Be consistent!
When you can start depending on the fact that certain constructs are always written the same, your eyes will get used to them - and as such, your reading/interpretation speed improves. It's like having a compiler behind your eyeballs!

Also, having consistent coding constructs makes it easier to search in code.
For example, if each and every assignment is written in the form "A := B", then I can find all assignments to 'A', by searching for "A :=" and finding all assignments from B would be done with ":= B". If you had used more or less spaces, these searches wouldn't have been 100% dependable.

Just my 5 cents - do whatever you like with these suggestions.

ajasja said...

I agree completely.

BTW @1:
I can do that in two keystrokes as well. I set up MMX to insert a default block on [Ctrl] + B :)

PMM said...

People learn that more code means more errors.
But that is only half the truth because it is only true if the complexity-levels are equal. And you might know about the problems about measuring complexity of code..

Anonymous said...

Ad 1: both have advanages and disadvantages. I find indentation more clearly visible in code with curly braces. But usually, I don't mind the difference.

2: I'd tell you just that. As Richard says, writing less code is good for maintainability. A GC is however not the only solution, RAII approaches are practical too.

3: Very true. There are some fancy things that can be done with C++'s STL algorithms and custom predicates, but as soon as your requirements get a bit more complicated, the explicit, non-functional way is both shorter and more readable.

4: Agreed. Comprehending interface sections is so much more straightforward than reading C++ headers or C#/Java code.

Anonymous said...

Indeed, the amount of code in itself is irrelevant, it's the code clarity that matters.

Sure, stats for clarity aren't as easy to obtain as couting the number of bytes or the number of lines. That's probably why people go for code size, because you have easy (but meaningless) indicators you can brag about.

I guess it's just the old pissing contest, men are proud of pissing farther, developpers are proud of doing it with the least code... even when that involves having billions of lines of code hidden in support libraries and frameworks.

Unknown said...

I absolutely agree.

Anonymous said...

Writing less code should not be the goal! Writing not only readable but also understandable code should be. This means sometimes writing less code, sometimes more code. More code may mean more bugs, but then again it's easier to make a mistake in a complex code than simple one.
I think the best example of "more simple code vs short but complex code" is regex. Sometimes it's wise to use regex (avoiding pages of if...else statements, so making code more readable), but sometimes figuring out a bug in a complex regex may take a lot more time than it would have taken if the code were written as simple statements.

Anonymous said...

It is called "The RAD fallout"

Anonymous said...

well, lets avoid writing comments - this will decrease file size and thus make code more readable and easy to understand :)

Jarle Stabell said...

Of course there is a movement towards writing less code. Not because we are lazy, but because we want to be more productive, we want to write (and read) the *essence* of the solution, not a lot of scaffolding/ceremony
tokens to support the essence.

1. You forgot the perfect "lazy" alternative to 'begin' and 'end', Python's (and F#'s) usage of indenting to specify block structure. :-)

2. Writing less code is a nice reason in itself, but it's not the main benefit of a GC.

3. Functional constructs can yield less lines of code, less brittle code and in some cases code which are much more amenable to parallell processing.
I believe that languages that don't easily support functional idioms will soon look hopelessly dated. It wouldn't surprise me if this is the main reason that Barry Kelly et al are redesigning the Delphi compiler.

4. You don't need code folding to replace the interface and implementation sections, help files or a treeview in the IDE can do the same (or better).

Anonymous said...

Garbage collection is not about saving having to type try...finally. If people think it's about that, they've majorily missed the point. And it's not about being lazy. It's about spending time where time should be spent on code.