Wednesday, December 17, 2008

A Corollary to Ockham's Razor

The popular phrasing of the maxim known as Ockham's Razor is, "the simplest solution is usually the right one."  This is not the original statement or William of Ockham.  He might better be paraphrased: "a solution with fewer assumptions is to be preferred."  That restatement, though still not precisely correct, captures the spirit but leaves out the concept of simplicity.  Karl Popper, the imminent epistemologist, would have us define simplicity as the "degree of falsifiability [sic]" of our solution; i.e., how easy is it to prove the solution incorrect?  Popper goes further:

Simple statements, if knowledge is our object, are to be prized more highly than less simple ones because they tell us more; because their empirical content is greater; and because they are better testable.

He could have well been talking about programming! If would follow that declarative programming, currying, constraint programming, and domain-specific languages are to be preferred over alternate paradigms, but so too would an entry to the obfuscated C contest and your average unreadable Perl program.  To rectify this seeming contradiction, we need to understand that a "simple statement", according to Popper, is one with fewer parameters--precisely because it is more testable.

So more testable code is better code, and we might induce that a test driven approach is to be preferred, insofar as the practice encourages the writing of simpler, more testable statements.  But, Ockham's razor is about solutions, not approaches.  So, what can we say about deciding between solutions?

I offer the Programmer's Corollary to Ockham's Razor:

To pick the best solution architecture, choose the one that consistently requires fewest number of parameters.

Tuesday, December 16, 2008

HOWTO: SQL Server Return Value with Enterprise Library

    int returncode = 0;
Database db = DatabaseFactory.CreateDatabase();
DbCommand dbCommand = db.GetStoredProcCommand("<your procedure>");
db.AddParameter(dbCommand, "@RETURN_VALUE", DbType.Int32, ParameterDirection.ReturnValue, String.Empty, DataRowVersion.Default, null);
db.ExecuteNonQuery(dbCommand);
if (!Int32.TryParse(Convert.ToString(dbCommand.Parameters["@RETURN_VALUE"].Value), out returncode))
returncode = -1;

The returncode local variable is useful, but generally not necessary. It's good to state your assumptions about the operation of external code explicitly.