July '08 Meet and Code Dinner Wrap Up

Tonights Meet and Code dinner was a huge success. We must have had 25+ people show up! I wish I had taken a head count, but tonight was definitely the first time that we have had to bring in extra chairs. The night started off with Harper Trow giving an excellent overview of the Ruby ecosystem. Then I stepped up and gave a quick overview of some basic Ruby concepts and syntax. Next Kevin Hazzard gave an awesome presentation on using IronPython and C# to call WCF SOAP web services and dynamically generate proxies that can then be used to call the web services! Pretty sweet no matter how many times I see it! Then last I got up again and gave a quick look at some of the code that I had used at my Function Programming Features in C# 3.0 talk and then translated it into Ruby to show how much less Ruby code it takes to get the same effect.

The C# code looked like this:

var domains = new List<string>
                  {
                      "www.google.com",
                      "www.yahoo.com",
                      "www.akamai.com",
                      "www.ask.com"
                  };

int pingCount = 20;                                    
IEnumerable<IEnumerable<int>> totals =
    domains.Select(d =>
                        d.Repeat(domain => new FakePing()
                                               .Send(domain).RoundtripTime, pingCount)
                            .Where(p => p != 0)
        );

IEnumerable<string> averages =
    totals.Select(p =>
               (p.Sum() / p.Count()).ToString()
        );

domains.Zip(averages).ForEach(p => Console.WriteLine(p[0] + ": " + p[1]));

With the helper methods looking like this:

public static IEnumerable<TResult> Repeat<TArg, TResult>
            (this TArg val, Func<TArg, TResult> func, int times)
{
    for (int i = 0; i < times; i++)
    {
        yield return func(val);
    }
}

public static T Fold<T>(
    this IEnumerable<T> list,
    Func<T, T, T> func)
{
    return Fold(list, func, default(T));
}

public static TResult Fold<TArg, TResult>(
    this IEnumerable<TArg> list,
    Func<TResult, TArg, TResult> func, TResult result)
{
    foreach (TArg item in list)
    {
        result = func(result, item);
    }
    return result;
}

public static IEnumerable<T[]> Zip<T>(this IEnumerable<T> list1, IEnumerable<T> list2)
{
    var enumerators = new[] { list1.GetEnumerator(), list2.GetEnumerator() };
    while (true)
    {
        int current = 0;
        var result = new T[enumerators.Length];
        foreach (var enumerator in enumerators)
        {
            if (!enumerator.MoveNext())
                yield break;
            result[current++] = enumerator.Current;
        }
        yield return result;
    }
}

public static void ForEach<TArg>(
    this IEnumerable<TArg> list,
    Action<TArg> action)
{
    foreach (TArg item in list)
    {
        action(item);
    }
}

The Ruby looked like this:

require 'FakePing'
require 'UtilityMethods'

ping = FakePing.new

domains = ['www.google.com','www.yahoo.com','www.akamai.com','www.ask.com']

result_groups = domains.map do |domain|
    10.repeat do
        ping.send(domain).roundtrip_time
    end
end

result_groups.map! do |group|
    group.select { |reply| reply != 0 }
end

averages = result_groups.map do |item|
    sum = item.inject(0) { |sum,ping_time| sum += ping_time }
    sum / item.length
end

(domains.zip(averages)).each do |z|
    puts "#{z[0]}: #{z[1]}"
end

With the helper method looking like this:

def repeat(&repeatable)
    result = []
    self.times do
        result << repeatable.call
    end
    result
end

Now most of that is library code which you would write once and not look at for years. And I'm certainly not switching from C# as my main development language, but it sure is nice to play around with this stuff and see things from a little bit different angle! It also amazes me how far C# 3.0 has taken us from what was possible in C# 2.0. Even looking at the code above, it is crazy thinking what it would have looked like if it was rewritten in C# 2.0.

Ninject Dependency Injection Screencast Number 2

My second screencast on Dependency Injection with Ninject just went up on Dimecasts.net. Go check it out at the link below:

Diving Deeper into Ninject -- Contextual Binding

Hope you enjoy it! Let me know what you think.

Reminder About July 2008 Meet and Code Dinner

This Thursday at 6:00pm 'til whenever is the July Meet and Code dinner. It is going to be held at SnagAJob.com's headquarters in Innsbrook. The address is 4880 Cox Road, Suite 200 Glen Allen, VA 23060. Below is the e-mail that will be sent out to the Richmond .net users group, hope to see you there!

This is going to be a good one! We will be discussing dynamic languages and we will be focusing on Ruby and Python. I will try to be presenting a little something about IronRuby and basic Ruby syntax. (IronRuby is Microsofts Ruby implementation that they are working on, in case you don't know)

Harper Trow has said he is going to prepare a few tidbits to show, and he has hooked us up with a friend (Mel Riffe) who does a lot of work with the local Ruby dev community.  Mel is going to come to help lead our discussion about Ruby and be able to interject wisdom from someone who works with it on a daily basis.

Also, the newly minted C# MVP Kevin Hazzard will be there, and he is going to be eschewing his C#-ness to show us a bit about his favorite dynamic language, Python. He will do this by way of the IronPython project. I'm really looking forward to this one.

All in all it looks like it is going to be a full night! Social time starts at 6 and the presentations start when they start. It all depends on how good the conversation is. The meeting officially ends at 8, but no one is going to kick us out. Come when you want and leave when you want.

Also, there will be food of some sort provided. Nothing too fancy, but who will notice with all of the dynamicness flying around?

Learning Ruby via IronRuby and C# Part 5

Click here to view the entire IronRuby via C# series

Welcome back for part 5 in my learning Ruby via C# series. In this post I want to cover hashes (or associative arrays) and arrays in Ruby. These two data structures are used quite often in Ruby, and so we are going to spend a little bit of time going over them. But first I want to clear up some mistakes that I made in the first post of the series. In the first post I had explained what attribute accessors were and I showed a class that looked like this:

class Person  
    attr_accessor :count  
    @@count2 = 0  
  
    def count2  
        @@count2  
    end  
  
    def count2(value)  
        @@count2 = value  
    end  
end

Well, that isn't exactly correct. Well, I was trying to show static variables in Ruby and I wanted to show the static version of "attr_accessor". The first item I wanted to clear up is that I used instance method in this class because we had yet to cover static methods. This was done on purpose, but I wanted to show it as static now. The second thing is that you can do this in a shortened manner using the cattr_accessor method. The "c" stands for "class" since Ruby calls these "class variables and methods" and not "static". The only problem is that this is part of ActiveSupport and not the standard Ruby libraries. ActiveSupport is a library of helper methods for Ruby on Rails, and currently has some issues running under IronRuby so I am not going to use it for now.

The second thing that I wanted to clear up, which actually was a mistake, is that the two "count2" methods are not what is defined. The second "count2" method should have an "=" between the word "count2" and the "(" that starts the argument list. So, if we don't use the "cattr_accessor" method, our class (using static methods) will look like this:

class Person  
    attr_accessor :count  
    @@count2 = 0  
  
    def self.count2  
        @@count2  
    end  
  
    def self.count2=(value)  
        @@count2 = value  
    end  
end

And then we could access these new static methods like this:

Person.count2 = 123
puts Person.count2

Phew, now we can finally get to the new stuff! Let's first talk about arrays. An array in Ruby is essentially the same as an array in C#. Lets say we wanted to declare an array of integers in C#:

int[] numberArray = { 1, 2, 3, 4, 5 };

Okay, now lets do the same thing in Ruby:

number_array = [1, 2, 3, 4, 5]

You can see that Ruby lets us define an array simply using square brackets and assigning the value to a variable. Now, while a C# array is immutable (meaning we can't modify it) a Ruby array can be modified. So, in C# in order to add the number "6" to our array above we would have to do this:

int[] numberArray2 = new int[numberArray.Length + 1];
Array.Copy(numberArray, numberArray2, numberArray.Length);
numberArray2[numberArray2.Length - 1] = 6;

But in Ruby, we could simply do this:

number_array << 6

This uses the "<<" operator, therefore making Ruby arrays more similar to a C# collection than a C# array. In fact, Ruby arrays has methods for deletion and insertion. If we were to say:

number_array.delete(3)

Then when we output the array, we would get "[1,2,4,5]". This is important because Ruby arrays are 0 based, just like C#. So, the "delete" method removes the item "3", not the index (in fact, if there were more than one "3", it would remove all of them). We would have to use the method "delete_at" in order to remove an item at an index:

number_array.delete_at(3)

We can also insert into the array using "insert" (the first parameter is the index, the second is the value):

number_array.insert(2,4)

So, what if we wanted to add an item to the end (without the "<<" operator):

number_array.push(7)

Okay, so we have a push method, what about pop? Of course, in Ruby you can use arrays just like stacks!

number_array.pop

Like I said before, in Ruby arrays are zero based, just like C#. They even use the same method to access the items. In C#:

int value = numberArray[0];

In Ruby:

value = number_array[0]

But what if we just wanted to see the last item in the array, but not remove it? In C# we would have to use the length of the array minus one:

int value = numberArray[numberArray.Length - 1];

But in Ruby, you can access arrays using negative indexes:

value = number_array[-1]

Negative arrays are indexed from the end of the array. How cool is that? Another cool thing you can do is use ranges to access an array:

number_array[0..2]

This would return "[1,2,3]". As you can see, the Ruby array is very flexible.

So, enough about accessing arrays, what if we want to do some operations on these arrays. Lets add up all of the items in C#:

int total = 0;
foreach (int i in numberArray)
{
    total += i;
}
Console.WriteLine(total);

And what about in Ruby?

total = 0
number_array.each do |i|
    total += i
end
puts total

Lets do it more efficiently in C# using the LINQ aggregate method (if haven't seen Aggregate (also called Fold) you can see an implementation and explanation here):

int total = numberArray.Aggregate((accumulator, i) => accumulator + i);
Console.WriteLine(total);

And then we will do it in Ruby using inject:

total = number_array.inject(0) { |accumulator, i| accumulator + i }
puts total

Sweet. You can really see how far C# has come to closing the gap in C# 3.0 with Linq. Before C# 3.0 and Linq we would be losing quite a bit of expressiveness here. Again, we can use the "select" method in C# and the "map" method in Ruby to transform items in an array. If we wanted to multiply each item in our array by 2, we could do this in C#:

var result = numberArray.Select(i => i * 2);

In Ruby we could do it like this:

number_array.map { |i| i * 2 }

Phew, I think we have had about enough with Arrays in Ruby. There is so many things that Ruby arrays can do, and we just don't have the space to cover all of it. Go check out the Ruby docs if you want to see all of it.

Well, I was going to discuss hashes, but I think that arrays went on for a lot longer than I had originally planned. This seems to be a recurring theme, but there is just so much to talk about! I hope that you enjoyed the post and in the next one we are going to start talking about hashes.

The Data Disconnect

I saw yesterday on Twitter that Sam Gentile had responded to Oren Eini's "Impedence Mismatch and System Evolution" post that was actually a response to Stephen Forte's "Impedance Mismatch" post. Phew, you got that? That is why I love the blogger world, it is like one big distributed, asynchronous conversation! In these posts there was a line stated by Stephen Forte that Oren had a problem with:

My first problem with ORMs in general is that they force you into a "objects first" box. Design your application and then click a button and magically all the data modeling and data access code will work itself out. This is wrong because it makes you very application centric and a lot of times a database model is going to support far more than your application.

Oren then went on to say that he "absolutely rejected" the statement that the database model is going to support far more than your application. Sam Gentile then chimed in that he fully agreed with this statement. I also agree with Oren's statement, but that isn't really why I am writing this blog post. I am writing this blog post because I think that we are at the edge of a huge schism in the data-centric application development community.

If you read Stephen Forte's post you will see that it was actually started by talking about the Entity Framework, and I think that is an important note to make. Why? Because these tools power is manifested by a fundamental shift in who owns an application's data. So, who does own the application's data? Well, I think that you can tell which way I lean just by the way I worded my last sentence. In my mind, the data is owned by the application that is reading and writing the data, and hopefully most people will agree with this. But what happens when you have numerous applications reading and writing the same data? Well, you have to move the control over the data into the database because the database becomes the single point at which all data passes through.

Historically stored procedures have been viewed as the data gatekeepers. You put a bunch of stored procs in your database and they shielded your tables from bad input, incorrect or incomplete data, etc... In fact many people have argued for putting business logic in stored procedures, because how else would you make sure valid data is entering the database if you have a multitude of applications hitting these stored procs? Well, you can't really. If you don't put business logic into your stored procs, then your data is only as good as the individual application that is entering the data. The proverbial "weakest link" problem.

How do you combat this? It is simple really, you move from a database-centric view, to a an application-centric view. The very thing that Stephen above was speaking out against. And I know that there are going to be people out there that are going to throw their hands up in the air and say "blasphemy!" when they read that. But I am not arguing that we throw the database out, or marginalize its importance, I am saying that the single point at which all data passes through needs to be pushed up. There needs to be application code responsible for transforming and validating data. In fact, most well thought out applications are using an architecture like this already. They have an abstraction layer that sits between the database and your domain model that shields you from schema changes and they also have business logic that ensures good data. The issue is that there may be several applications hitting a database, each with their own abstraction layers that are operating directly against the database schema.

All of that data should be funneled through a single application! If you see the need for two applications to be hitting the same schema, then you should at least define a thin service layer between the database and those two applications. Even if the applications need the same schema now, they most likely won't need the same schema a few months, or years, from now. Business logic just doesn't work like that.

I am not advocating anything new here. People have been discussing it for years, it is called Service Oriented Architecture. And yes, I know that SOA is probably the most overloaded term in the history of software development, but in its most basic form it represents an architecture where you have a bunch of loosely connected services. So, what are those services? Well, they could take many forms, but they are all going to be some application that is sitting in front of a data back-end. And in this layer, all of our bajillion lines of business and application logic reside. The data is abstracted behind many layers so that we can mold, transform, and even query from multiple sources. All of this is hidden from the application or person that requests the data, just as it should be.

If you have a single rich layer of business and application logic that can be as thin or as thick as you need it, that can be changed and molded to produce the data you need, and can keep knowledge of your schema out of the hands of many other applications, then how can this be a bad thing? In my mind I would think that even the data people would love this, because it means that the database schema can be much more flexible and can change more rapidly to suit the needs of the company. Or not change at all, since the service layer can transform the data, if the needs of the enterprise dictate this.

But where do the ORM tools come into this? If you are looking at a database as the center of the application, with multiple applications hitting the same database, then an ORM solution would probably look less realistic for you. ORMs biggest advantages come into play when they are generating their own SQL (so as to avoid having to maintain separate stored procs) and when you let the database schema stay relatively simple and have the translation layer massage the data into the exact format you need. These goals can often conflict with the database-centric view of an application, which likes to keep more of this control inside the database.

So, is the data divide that I am talking about just an argument between the data and service centric approaches? That is the way that I see it. Did I think that we would still be arguing this point in 2008? Nope.