Imperative to a Fault
One of the most alarming things to me in the industry today is the almost superstitious aversion to the use of expressions. For example, consider the following snippet:
protected virtual bool SameNumberOfParametersAndValues
(DbCommand command, object[] values)
{
int numberOfParametersToStoredProcedure = command.Parameters.Count;
int numberOfValuesProvidedForStoredProcedure = values.Length;
return
numberOfParametersToStoredProcedure == numberOfValuesProvidedForStoredProcedure;
}
When I first came across this I thought it was a joke. But then I realized this was a recommended best practice! This gem of a function is a method of the Database class in the latest version of the Enterprise Library from the Patterns and Practices group at Microsoft. This is the kind of code they are saying we should all be writing!
Never mind the run-time inefficiencies of using this method (we hope the c# compiler would be smart enough to optimize it away, but it's likely not the sort of thing for which a compiler-writer would expect to have to optimize), it's almost impenetrable conceptually. In the name of making the code 'easier to read' they have completely hidden what is actually happening. Are we seriously claiming that the simple expression command.Parameters.Count == values.Length is unreadable? This really warranted building a separate function, then declaring local variables to store the values to be compared, then comparing the values? And yes, I realize the function is virtual, the point still stands within the function itself.
The thing is, I wish this were an isolated instance and that code snippets like this were few and far between, but this is not the case. I come across code like this on a daily basis, code that avoids the use of composition of expressions as though it was some toxic ingredient. As though in order to write good code, each line must contain only a single operation (which BTW the above code does not reach this ideal, it accesses a property of a property, as well as initializes a variable on the same line on which it is declared).
Now the first argument in support of this extreme position is that it makes it easier to debug. Well, that's simply not the case with a modern debugger, it's just as easy to watch the value of a property as part of an expression as it is to watch a local variable. No dice. Not to mention the fact that this is the implementation tail wagging the programmer dog. Shouldn't our first priority be to write code that is easy to read and understand?
I suspect that the 'it's easier to debug' argument is really just an attempt to defend this style of programming. I believe that what is really at fault here is languages that have beaten the expressive tendency out of developers. Languages like Visual Basic that until very recently completely lacked the ability to pass the results of an expression as an argument to another operation. In a language like that, it's easy to see how an 'Imperative to a Fault' style would evolve and even become a 'best practice' leading to abysmal functions like the one above, to the point that even now, when the language does provide closure, the 'best practice' prevents its usage!
Far better to embrace the expressive potential of languages and improve readability and maintainability of code by moving towards the more declarative ideal.
Bryn Rhodes
Alphora