AJ's blog

April 27, 2008

I can’t help but notice…

… that functional programming might be the next big shift in general purpose development paradigms.

The other day I realized a trend that may be decisive for the evolution of our development environment in general: Functional Programming! It is not that I did not see the symptoms. It is just that it took that long to realize the breadth of it. (I’m in good company, though.)

Yesterday…

… it started quite unobtrusive.

We got generics and with them (hardly mentioned as more than syntactic sugar) type inference.

In retrospect it even seems misleading that generics were discussed as something akin to C++ templates. The technical differences may seem superfluous at first, yet some advanced techniques with templates, orthogonal libraries such as STL (only recently available as STL/CLR for managed code) and template meta-programming have never been broadly considered for generics. Rather type inference plays a major role with generics, effectively pushing the burden of type safety from developer to compiler.

We got anonymous methods, which was at that time hardly worth the effort and not at all a justified language change — if looked at in isolation.

We got iterators, which was again a feature no one had missed, much less asked for.

Several features, seemingly unrelated, some rather tiny unmotivated additions to the language.

Today (the obvious)…

… we have LINQ.

LINQ has been introduced at the PDC 05 by Anders Hejlsberg et al. as kind of “complied SQL statements”, “type safe SQL”, and “unified query language”, thus the name of course.

The language features that make up LINQ rely on the above language features. And with LINQ those pieces suddenly fall into shape. Type inference for anonymous types and together with generics as general foundation, anonymous methods for lambdas, iterators for deferred execution. A concise system.

And this is how LINQ is seen by many people: Type safe queries. Something to replace ugly ADO.NET code over SQL strings with beautiful and compiler checked C# statements. Who can blame them, that’s how it got introduced.

What those people miss is the less obvious force behind LINQ. It’s functional programming, as Anders itself explains — not the other way round, as presented in “The Evolution Of LINQ And Its Impact On The Design Of C#”.

It’s not that the trend to functional programming is kept secretly. Matter of fact, the term is mentioned quite frequently in relation to LINQ. And there’s other evidence, like the new .NET language F#, incidentally written by Don Syme, the man who built generics for .NET. And there’s enough bloggers out there, talking about the topic.
It’s more that the average corporate developer, the kind that has more than enough to do getting his job done, is not directly exposed to this information. Therefore he picks up only occasional hints at best, not connected, not nearly enough to identify a larger trend. Many of them may not even be aware about the degree to which they have already exposed to functional programming bits and pieces.

Today (the not so obvious)…

… there is a lot of talk around functional programming going on in the blog sphere. Some examples:

Regarding lambdas have a look at Wes’ blog to learn about currying, continuations, monads. Other bloggers have written about other language features (e.g. extension methods). Luca tries to bring F# features to C#.

Also there has been a lot of noise around one of the tenets of functional programming: immutable data types. Just as we got new collection classes with generics, we may get immutable ones sometime in the future.

If you like to read up on immutable data types, Roy has compiled a list of related blog posts; I found Erics series to be the best, as he addresses not only the purpose but also the feasibility (consider the insolence, a list that does not change, how can that be feasible?). And he addresses null values (not exactly part of the functional universe) better than the others.

Another interesting application is MoQ (if not by itself, then as an example for the functional approach), a LINQ based mock framework. It may serve as indication that even stuff that is not directly related to functional programming may come in a functional shape.

Tomorrow…

… — and this is strictly a personal guess — the trend will continue. If anything it will diverge in different areas. Functional programming in general and F# idioms in particular may contribute to our languages, the patterns we use, and the libraries. F# may not only be the first functional language to decisively enter the .NET environment, it may be the very first functional language with at least the potential to become a mainstream language

The driving force behind this is something that Anders hinted at it in his interview above, and that Pat Helland pointed out quite clearly at the TechEd: The future is parallel. And functional programming is so much more suited to parallel processing than imperative programming. Matter of fact, Parallel LINQ (PLINQ) is already working in that direction.

Right now…

… that’s enough gazing in the crystal ball. What’s the consequence (provided you share my view)? Today probably nothing. None of my daily work is affected, beyond using LINQ as a nice tool. Tomorrow perhaps still nothing, as I may be totally wrong. All I can recommend is this: Try to see the bigger picture behind LINQ and keep watching for the trend. For if it’s the other way round, you may be tomorrows next VB guy, like the one in the next cubicle that never mastered inheritance and exceptions.

As an afterthought: I’m not aware that this functional programming trend happened somewhere outside the Microsoft space. This is contrary to the dynamic languages trend. And I’m honestly not sure what the implication is.

That’s all for now folks,
AJ.NET

kick it on DotNetKicks.com

April 20, 2008

LINQ to SQL Reality Check

Filed under: .NET, .NET Framework, C#, LINQ, Software Architecture, Software Development — ajdotnet @ 2:37 pm

After the introduction and checking LINQ to Objects, this is the second part of the Reality Check story.

Employment of LINQ to SQL

OK, off with the gloves and hard core LINQ ;-)

image But first some background: LINQ to SQL manifests itself as a .dbml file supported in VS2008 by a respective designer. Via server explorer one can add tables, stored procedures, and other DB objects to the designer. SQLMetal, the code generation tool behind the scenes of LINQ to SQL, is used to generate code for the data context class with static methods for stored procedures. Tables are mapped to entity classes, columns to properties, in a trivial fashion but non-trivial way. E.g. the ID column:

[Column(Storage="_CustomerID", DbType="UniqueIdentifier NOT NULL")]
public System.Guid CustomerID
{
     get
     {
         return this._CustomerID;
     }
     set
     {
        if ((this._CustomerID != value))
        {
            if (this._Customer.HasLoadedOrAssignedValue)
            {
                throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
            }
             this.OnCustomerIDChanging(value);
             this.SendPropertyChanging();
             this._CustomerID = value;
             this.SendPropertyChanged(“CustomerID”);
             this.OnCustomerIDChanged();
         }
     }
}

As you can see, the set method goes at length to announce the change of the value. The generated entity properties support various “events” by means of partial methods, and the entity classes implement respective interfaces (INotifyPropertyChanging and INotifyPropertyChanged).
In addition to properties for columns, the entity classes provide properties for relationships (supporting lazy loading) if they have been modeled accordingly.

All generated classes are realized as partial classes and can be adorned with custom code without problems. All classes are created in one big source file, one can however influence the class names, namespaces and some other parameters that affect code generation.

Now back to the prototype application…

The prototype application uses “poor man’s O/R mapping”, i.e. data readers to access the DB and manual mapping to POCOs. It even doesn’t use reflection (dude, it’s a prototype application), thus it is by no means representative.

Anyway, I’ll just present old and new code as before, again, relevant parts in bold. 

3. Example: Reading a customer (single object) from the database.

const string SELECT_CUSTOMER_BY_ACCOUNT = “select * from customer where MainAccount=@MainAccount”;

Customer FindCustomer(int mainAccount)
{
     Customer c;
     using (SqlConnection con = OpenConnection())
     {
         using (SqlCommand command = new SqlCommand(SELECT_CUSTOMER_BY_ACCOUNT, con))
         {
             AddParameter(command, “MainAccount”, mainAccount);

             using (SqlDataReader reader = command.ExecuteReader())
             {
                 while (reader.Read())
                 {
                     c = FillCustomer(reader);
                     return c;
                 }
             }
         }
     }
     return null;
}

private static Customer FillCustomer(SqlDataReader reader)
{
     Customer c = new Customer();
     string name;
     for (int i = 0; i < reader.FieldCount; ++i)
     {
         name = reader.GetName(i).ToLower();
         switch (name)
         {
             case “id”: c.Id = reader.GetGuid(i); break;
             case “mainaccount”: c.MainAccount = reader.GetInt32(i); break;
             case “name”: c.Name = reader.GetString(i); break;
         }
     }
     return c;
}

Nothing but boilerplate code. And the rewrite using LINQ to SQL:

CustomerLinq FindCustomerLinq(int mainAccount)
{
     DataClassesDataContext dc = new DataClassesDataContext();
     var customerList = from cc in dc.CustomerLinqs where cc.MainAccount == mainAccount select cc;
     return customerList.FirstOrDefault();
}

About 35 LOC (still 20 LOC if the mapping is left out) vs. 6 LOC. No need to comment on that I guess…

To provide a complete picture (and because I didn’t want to change the whole application to new entity classes) I also tried the “separate entity assembly” approach. This code also maps the generated entities to layer independent entities:

Customer FindCustomerLinq2(int mainAccount)
{
     DataClassesDataContext dc = new DataClassesDataContext();
     var customerList = from cc in dc.CustomerLinqs where cc.MainAccount == mainAccount select cc;
     var cl= customerList.FirstOrDefault();
     if (cl!=null)
         return new Customer() { Id= cl.ID, MainAccount= cl.MainAccount, Name= cl.Name, TotalBalance= cl.TotalBalance };
     return null;
}

As there was no appropriate constructor, object initializers kicked in nicely. Of course this would be the next mapping method, but not to complicated and, contrary to the data reader mapping above, it would be fully type safe (unless you employed reflection, of course).

4. Example: Read all accounts (i.e. a list) for a customer.

const string SELECT_ACCOUNTS_BY_CUSTOMER= “select * from vAccount where CustomerID=@CustomerID order by SubAccount”;

IList<Account> IAccountTable.GetAccounts(Guid customerId)
{
        IList<Account> list = new List<Account>();
        Account a;
        using (SqlConnection con = OpenConnection())
        {
                using (SqlCommand command = new SqlCommand(SELECT_ACCOUNTS_BY_CUSTOMER, con))
                {
                        AddParameter(command, “CustomerID”, customerId);

                        using (SqlDataReader reader = command.ExecuteReader())
                        {
                                while (reader.Read())
                                {
                                        a = FillAccount(reader);
                                        list.Add(a);
                                }
                        }
                }
        }
        return list;
}

private static Account FillAccount(SqlDataReader reader)
{
        Account a = new Account();
        string name;
        for (int i = 0; i < reader.FieldCount; ++i)
        {
                name = reader.GetName(i).ToLower();
                switch (name)
                {
                        case “id”: a.Id = reader.GetGuid(i); break;
                        case “mainaccount”: a.MainAccount = reader.GetInt32(i); break;
                        case “subaccount”: a.SubAccount = reader.GetInt32(i); break;
                        case “balance”: a.Balance = reader.GetDecimal(i); break;
                }
        }
        return a;
}

With LINQ:

IList<AccountLinq> GetAccountsLinq(Guid customerId)
{
     DataClassesDataContext dc = new DataClassesDataContext();
     var accountsList = from aa in dc.AccountLinqs where aa.CustomerID == customerId orderby aa.SubAccount select aa;
     return accountsList.ToList();
}

The same LOC relation as above. Mapping the generated entities may be a little more effort, but still far less than in the classical version. And since I called ToList() I didn’t even have to change my interfaces. With separate entities one would have to traverse the list and translate each entry. But again, no big deal and less work than without LINQ.

Conclusion:

The rate of code reduction with LINQ to SQL is even higher than with LINQ to Objects. This is something that’s very hard to ignore.

On the other hand, there is the architectural issue to be solved. In my opinion the biggest obstacle with LINQ to SQL is the fact that all code, entities and data context, are created in one big source file, thus I cannot separate them. I cannot put the entities in an entity assembly as mandated by the architecture without also putting the data context class into that assembly as well, exposing the database to anyone unduly interested. The alternative would be to have a second set of entities, one for the data access and one to flow across the layers. And respective mapping code. Doable as I checked, but not a nice prospect.

BTW, this time I used nearly every aspect of LINQ: The code contained Query Syntax, Extension Methods, Lambdas, Object Initializers, and Type Inference. And with System.Data.Linq a library is used that heavily relies on Expression Trees. Anonymous Types is the only missing part.

Final judgement:

All in all, LINQ proved to be such a useful addition to the developers toolbox that it cannot be ignored, even if it has its own problems. And while it is often seen as “better SQL”, this is already shortsighted. My earlier posts as well as all the fuss about functional programming in general should be indication enough that this is just where it begins.

That’s all for now folks,
AJ.NET

kick it on DotNetKicks.com

April 13, 2008

LINQ to Objects Reality Check

Filed under: .NET, .NET Framework, C#, LINQ, Software Development — ajdotnet @ 2:38 pm

The following post is actually a translation of a post I wrote last year for our internal company blog. It’s already gained some moss, so to speak (LINQ is released; isn’t there some new technology to blog about? ;-) ), but it may still serve as motivation for those who have successfully avoided the LINQ hype so far. And I kind of need it as introduction to some other posts I have in mind.

Here we go…

To me, LINQ seemed to be quite interesting, but until recently it was exactly that: a semblance — and one that has to be proved. I didn’t want another bunch of test code showing the exact problems that LINQ was built to solve and LINQ (surprise!) solving those problems. I wanted to see how LINQ fared in a real world scenario, i.e. based on existing code not built with LINQ in mind.

I have a little prototype application at my disposal. Not exactly a productive application, but near enough for my purpose. It’s a simple 3tier web application, as outlined in an earlier post.

My experiment took three steps:

  1. Migration to VS2008 und .NET 3.5
  2. Employment of LINQ to Objects
  3. Employment of LINQ to SQL

Here are my experiences — the LINQ to Objects part in this post, the LINQ to SQL part in the next one. Valuations are purely subjective ;-)

The migration ran smoothly enough, unit test assemblies had to migrated manually and code analysis spit out a lot of new warnings (which may be an issue in bigger projects and if you like “warnings as errors”). Otherwise the application ran without problem.

Employment of LINQ to Objects

LINQ to Objects is only a using statement away. All you have to do is adding the following line (and the respective assembly reference, if not done already):

using System.Linq;

Afterwards I scanned the existing code for rewrite candidates. You don’t need to understand the gory details of the following samples, the important thing is the relation between the non-LINQ and the LINQ versions. The relevant parts of the samples are in bold.

1. Example: A code fragment that reads all accounts of a customer and calculates the balance.

Customer c= ….
IList<Account> al = AccountTable.GetAccounts(c.Id);

c.TotalBalance = 0;
foreach (Account a in al)
     c.TotalBalance += a.Balance;

The rewrite with LINQ:

Customer c= …
IList<Account> al = AccountTable.GetAccounts(c.Id);

c.TotalBalance = al.Sum(a => a.Balance);

Effect: Calculating the sum is down from 3 lines of code to one line of code — and quite a bit more readable as well.

2. Example: Find a sub account in a sub account list.

IList<Account> list1 = AccountTable.GetAccounts(c.Id);

Account a= null;
foreach (Account a1 in list1)
{
     if (a1.SubAccount == subAccount)
     {
         a = a1;
         break;
     }
}

Another “classical” version could have been provided via an anonymous delegate, though only available with the class List<>, not the interface IList<>:

IList<Account> list1 = AccountTable.GetAccounts(c.Id);

List<Account> list2 = list1 as List<Account>;
a = list2.Find(
     delegate(Account test)
     {
         return (test.SubAccount == subAccount);
     });

And the LINQ version:

IList<Account> list1 = AccountTable.GetAccounts(c.Id);

Account a = list1.First(test => (test.SubAccount == subAccount));

The effect: LOC down from 9 (6 with delegate) to 1. And more readable. And applicable on the interface (rather than the List<> class).

Conclusion:

In the cases shown above, LINQ to Object provides way more efficient code, less code, better readable code. The cases were all related to list operations. And this is by no means tied in any way to database operations, i.e. any code may profit from this. On the other hand, I didn’t find any other use cases beside list operations in the existing code.

At a closer look only a subset of the LINQ features were involved: Extension methods, lambdas, and the System.Linq library. This is not an issue, just stating a fact. It’s not that the query syntax and other features aren’t available without database, it’s just that I didn’t need them.

End of part 1, the short and easy on, actually. But very convincing so far. The next post will look into LINQ to SQL.

That’s all for now folks,
AJ.NET

kick it on DotNetKicks.com

The Shocking Blue Green Theme. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 244 other followers