Ruby 1.8 (today) vs C# 3.0 (some future date)

March 25, 2006 - 4 minute read -

One of the big features I keep hearing .NET developers talk about is something called Language Integrated Query (LINQ). LINQ is an Object Query Language (OQL) technology that is slated to be integrated into .NET 3.0. In the general sense an OQL allows you to "query" an object graph much the same way you would query a relational database. LINQ querys even look quite a bit like SQL queries.

The LINQ implementation ends up relying on the introduction of Lambda functions in the core .NET 3.0 language. Lambda functions are a powerful way of encapsulating a (potentially reusable) block of code. The block of code can then be stored in a variable, passed to other methods, etc. As I discussed in a previous post Ruby Features You'll Wish You Had In Other Languages these blocks can be used to implement simple patterns like Observer and Strategy. They also come in real handy for doing things like sorting and filtering lists as you'll see in the example below.

LINQ Query:

string[] names = { "Geoff", "Jessica", "Mike", "Megan",
                                    "Priscilla", "Jack", "Alma" };
    IEnumerable<string> expr = from s in names
                               where s.Length == 5
                               orderby s
                               select s.ToUpper();
    foreach (string item in expr)
      Console.WriteLine(item);

This is a really handy feature.

Ruby has lambda functions, blocks and procs as well as built in support for a lot of filtering of arrays.

# define the array
names = [ "Geoff", "Jessica", "Mike", "Megan", "Priscilla",
             "Jack", "Alma" ]
# find all names that are 5 characters long, sort them
# alphabetically and make them uppercase
expr = names.select {
    |n| n.length == 5
}.sort.collect { |n| n.upcase }
# print the results to standard output
expr.each {|n| puts n }

I'm a big fan of Object Oriented languages. The Ruby Way seems much more of a natural OO construct to me than the SQL/LINQ type syntax. Fortunately LINQ also introduces more of an OO syntax along with lambda functions that Ruby people (and Lispers) have come to love.

Func<string , bool>   filter  = s => s.Length == 5;
Func<string , string> extract = s => s;
Func<string , string> project = s => s.ToUpper();
IEnumerable<string> expr = names.Where(filter)
                                .OrderBy(extract)
                                .Select(project);

Or the slightly more compact way:

IEnumerable<string> expr = names
                           .Where(s => s.Length == 5)
                           .OrderBy(s => s)
                           .Select(s => s.ToUpper());

This code ends up looking remarkably like the Ruby example above doesn't it?

The power of blocks and lambda functions in Ruby is the fact that they are so widely used in the core libraries of the language. They are an integral and extremely powerful part of the language so people become used to them very quickly. Only time will tell how well integrated the LINQ concepts are into the core .NET languages. Hopefully it will be better integrated than the Generics where in the Collections classes (where they created an entirely new namespace for the Generic collections instead of extending the existing ones). I look forward to this new addition to the .NET family of languages. But you don't have to wait to try these interesting and powerful features if you check out Ruby. Oh, and Ruby runs on the .NET CLR today, so check out Ruby CLR too.