A software package a day: LINQ to Whatever

Microsoft’s LINQ isn’t a software package in the traditional sense, but instead a way to extend and enhance software that runs on the Common Language Runtime (more commonly known as “.NET”). I believe that it is one of the most important releases from Microsoft in a long time, despite not being traditional “software”. The reason that I believe this is simple: it puts the power of declarative and functional programming front and center in a highly popular programming environment. What do I mean by “declarative and functional"? A little background will help.

Declarative programming is simply programming by “declaring” what you want to happen. The most common declarative language in use is today SQL, which is a query language for databases. In a traditional procedure language data access is a chore (some psuedocode to illustrate):

open "table"
open "another"
for each record in table
   if record.column equals something then
      for each innerRecord in another
      	 if innerRecord.column2 equals somethingElse 
         and record.joinColumn equals innerRecord .joinColumn then
            *display the record*

close “another”
close “table”

This code simply looks through two tables, doing something with records that have a condition true in the “record” table and a matching record in the “another” table with some other condition, then we will display it. Real life code of this nature is even more complex to do by hand because we want to sort (I left that out) and often we can speed up access via “indexes” (like the index at the back of the book, it helps the database find the proper “page” where something is found). I have also left out how the “for” loops get new records and more details. Now look at the same process in SQL:

SELECT * FROM table 
INNER JOIN another
ON table.joinColumn = another.joinColumn
WHERE record.column = ‘something’
AND innerRecord.column2 = ‘somethingElse’ ORDER BY another.sortColumn

In the SQL version we don’t manually loop or run conditionals, we simply ask for the data by filling in a fairly English looking statement. This version is more powerful than the longer example above because we have sorted the results by “another.sortColumn” and we will automatically use any declared indexes. For more complex statements the advantage of SQL grows as you don’t have to worry about edge cases, rewinding the tables if multiple items match (especially cumbersome if 3 or more tables are involved in traditional code). The downside is that the user doesn’t control some of the fine details, but years of database development have created query optimizers that deal with most cases correctly the first time and profiling tools that allow the database administrator to optimize the database for the workload it sees: something impossible to do with traditional programming unless the database administrator works closely with the programmers.

All of this is well and good, but what does this have to do with LINQ? Well, the main feature of LINQ is that it brings a SQL like syntax into the .NET languages that allow the same advantages to be garnered. However, while LINQ to SQL is neat in that it will allow data access like SQL will, LINQ to XML allows similar query and update methods to be declaratively applied to XML and LINQ to Objects allows the same power to be applied to your own (or third party) objects in your code.

In other words, LINQ provides a declarative syntax for something that traditionally was done via tedious procedural code. Need to reset all your combo boxes on a form? No problem: just query the controls on the form and operate on those that match a criteria. Need some complex XML? Write it in a structure that indents the same way as the resulting XML, with an assurance that you never will have “orphan” nodes. Have a set of data structures that you need to perform a complex query? Write a LINQ to Objects query using a “join” and iterate over the result set.

LINQ doesn’t cure cancer though. It is powerful and once understood much simpler than traditional code. Bundling along for the ride with LINQ is that any language supporting LINQ also gained functional features (a subject for another day, but suffice it to say that they make the declarative model easier to implement). This means that functional features are being learned by mainstream programmers and not just an ivory tower subject restricted to academia and a limited number of coders who “got” how to do it.

Declarative code has fewer errors and is shorter. Functional programming can make for more robust code as well as it becomes easier to reason about your software. Tossing both into the .NET experience was one of the best things that Microsoft has done in a long time.