Talking Dynamic Lanugages with Neal Ford

I spent a couple of hours chatting with Neal Ford from ThoughtWorks yesterday. Ted Neward had virtually introduced us a few months ago and he was in town for MTS, so he arranged a meeting. I had asked Ted to introduce me to some dynamic language folks for some research and public debate purposes, and Neal was one of the people he hooked me up with. Unfortunately, this was right before I changed roles and got real busy. Of course, dynamic languages in general and Ruby in particular plays a large role in Edge Architecture, so I’m thankful Neal took the time to drop me a line and meet with me.

Above all else, talking to Neal made me realize that I just don’t know enough about dynamic languages, which limits my ability to discuss them. To date, I’ve flirted with them, but haven’t made a real commitment. For example, I’ve played around with Instant Rails, but hadn’t actually installed Ruby yet. It was time to re-image my dev partition anyway, so I’m going to try using Ruby exclusively for a while.

Here’s a brain dump of some of what we talked about. Not sure what it all means yet, so I’ll try and refrain from making commentary.

  • Hungarian notation for interfaces (i.e. ISomething) is a big code smell. This has nothing really to do with Ruby or dynamic languages, but it’s an important point that I wanted to include here. Neal’s point is that the interface defines the semantics of the type and the concrete class is an “implementation detail”. In other words, contract-first isn’t just for web services. Apparently, ThoughtWorks doesn’t use ADO.NET directly primarily because the interfaces “aren’t pervasive enough” and are difficult to mock out. Also, they’re using Rhino Mocks which I wasn’t previously aware of.
  • For all the debate about static vs. dynamic languages, it seems like the value Ruby brings is in meta-programming rather than dynamic typing. Certainly, that’s one of the big differentiators for Ruby vs. other dynamic languages like Python. While Rails has pushed the popularity of Ruby thru the roof recently, Neal seems much more enamored with Ruby than Rails.
  • There is an even bigger gulf between dynamic and static typing proponents than I had thought. I brought up Singularity, which uses static typing exclusively to deliver a provably dependable system. Neal disagreed with that approach, pointing out that “tests are the best way of encoding the specification of the system” rather than compile time checking. Given my lack of expertise in this space, I’m withholding comment (for now) but I’m guessing the truth is somewhere in the middle.
  • However, while the dynamic vs. static typing gulf is big, meta-programming is potentially the bridge. I don’t believe meta-programming is exclusive to dynamic languages. Certainly, some of the new features in the “Orcas” versions of C# and VB bring more expressiveness to the languages while still remaining type safe.
  • All this meta-programming leads to domain specific languages. Ruby has strong support what Martin Fowler called “internal DSLs”, but Neal thought over time the focus would shift to external DSLs as they are more expressive and not constrained by the semantics of an existing language. Obviously, we’re pretty heavily focused on DSLs. However, Neal did think our focus on graphical DSLs is misplaced. He called them a “hangover” from CASE/UML tools. He rightfully pointed out that “business analysis speak English”.

All in all, it was time well spent. Neal, I hope we can pick up the conversation again sometime.

LINQ + WAP == Coolness

I never really missed Web Application Project support in VS05 until I realized what I could do with it. I’ve been experimenting with LINQ and wanted to be able to use it in a web application I’m prototyping. Under the file system model, there’s no easy way to change the compiler used for dynamic compilation of web pages. With WAP, it’s no problem.

If you’ve got both WAP and LINQ installed, you can enable LINQ support in your web apps by doing the folllowing.

  1. Open your WebApp.csproj file in notepad.
  2. Add references to System.Query, System.Data.DLinq and System.Xml.XLinq.
  3. Change the Target Import element to import $(ProgramFiles)LINQ PreviewMiscLinq.targets instead of $(MSBuildBinPath)Microsoft.CSharp.targets

That’s it! Seems simple, but it let me bind a GridView to the following function:

public static IEnumerable GetTitles()
{
  var con = new SqlConnection(Properties.Settings.Default.PubsConString);
  var db = new Pubs(con);
  var q = from t in db.Titles select t;

  return q;
}

It would be even cooler if I could simply write that query in the conext of the ObjectDataSource, but of course ObjectDataSource doesn’t know about LINQ. I imagine a LinqDataSource would be a logical next step.

The Dual Schema Problem

A few months ago, Ted Neward wrote a great article about the history of the Object Relational Impedance Mismatch problem and how LINQ is addressing it in a new way. Basically, LINQ is introducing new language abstractions and complementary libraries to enable queries as a first class concept within the language. However, I don’t believe that O/R Impedance Mismatch is the whole problem. More specifically, it’s a follow-on problem to what I would call the Dual Schema problem.

In a nutshell, the Dual Schema problem is that you have to design and implement two separate versions of your persistent entities. There’s the in memory version, typically written in an OO language like C# or Java. Then there’s the on disk version, typically written in SQL. Regardless of the difficulties translating between the two versions (i.e. the aforementioned impedance mismatch), you have to first deal with the complexity of keeping the two versions in sync. While LINQ does a great job eliminating much of the friction translating between on disk and in memory formats, it could go much farther by eliminating the need for translation in the first place.

A variety of solutions to the Dual Schema problem have evolved, primarily outside the hallowed halls of enterprise vendors (i.e. MS and others like us). One such solution is Ruby on Rails. In a Rails environment, I simply declare the existence of a given persistent entity:

class Person < ActiveRecord::Base
end

The ActiveRecord base class (a standard part of Rails) will dynamically create methods and attributes on the Person object at runtime, based on the schema of the People table in the database. (Rails is smart enough to understand English plurals, hence the automatic connection of Person and People.) So technically there are still two schemas, but the in-memory version is automatically derived of the on-disk version.

(Note, DLinq provides a conceptually similar tool – SqlMetal – that can generate the static types from a given database schema. However, as static types they have to be defined at compile time. So while SqlMetal reduces the effort to keep schemas in sync, it doesn’t eliminate it the way Rails does.)

By slaving the object schema to the database schema, Rails essentially solves the Dual Schema problem. The problem with the Rails approach is that defining a database schema requires a significant amount of skill and effort. Defining classes is typically trivial in comparison.The fact Rails allows you to implement a persistent entity with almost no code doesn’t help you much if you have to write and maintain a ton of SQL code to define your database schema.

I believe the Rails model is actually backwards. It would be much better for the developer if they could define their persistent entity in code and slave the database schema to the object model instead of the other way around.

Of course, this approach isn’t exactly news. In his article, Ted writes of the rise and fall of OO database management systems, which were supposed to solve the Dual Schema and Impedance Mismatch problems. I’m certainly not suggesting a return to the heyday of OODBMS. However, one of the reasons Ted points out OODBMS failed was because big companies were already wedded to RDBMS. But those big companies are the short head. As you move down the long tail of software, relational database as the primary storage paradigm makes less and less sense. For the vast majority of applications, relational databases are overkill.

Ted’s other point about OODBMS is that loose coupling between the data store and the in memory representation is a feature, not a flaw. He’s totally right. But can’t we advance the state of the art in database typing to the level of modern day OO languages? How about eliminating anachronisms like fixed length strings? What if we derive the database schema from the object model – Rails in reverse if you will – but is still loosely coupled enough to allow for schema evolution?

An example of this code-centric model for data storage is Consus. It’s written by Konstantin Knizhnik, who has written a bunch of open source, object-oriented and object-relational databases across a wide variety of languages and execution environments, including CLR. Consus is actually written in Java, but he provides version compiled for .NET using Visual J#. Consus lets you to define your data either as tables or objects. So you can do this:

Statement st = db.createStatement();
st.executeUpdate("create table Person (name string, address string, salary bigint)");
st.executeUpdate("insert into Person values ('John Smith', '1 Guildhall St.', 75000)");
ResultSet rs = st.executeQuery(
    "select name, address, salary from Person where salary > 100000");

Or you can do this:

class Person {
    String name;
    String address;
    long salary;
    Person(String aName, long aSalary, String aAddress) {
        name = aName;
        salary = aSalary;
        address = aAddress;
    }
};

Person p = new Person("John Smith", 75000, "1 Guildhall St.");
ConsusStatement st = db.createStatement();
stmt.insert(p);
ConsusResultSet cursor = (ConsusResultSet)st.executeQuery(
    "select from Person where salary > 100000");

Consus also handles OO concepts like derivation and containment. Of course, the embedded queries are ugly, but you could imagine DLinq style support for Consus. In fact, one of the primary issues with Consus is that it supports both object and tuple style queries. When you explicitly request tables (i.e. “select name, address salary from Person”), you’ve got a tuple style query. When you don’t (i.e. “select from Person”) you’ve got an object style query. Of course, the issues with tuple style queries are well documented in Ted’s article and is exactly the problem that LINQ is designed to solve.

(Konstantin, if you’re reading this, drop me a line and I’ll look into getting you hooked up with the LINQ folks if you’re interested in adding LINQ support to Consus.NET.)

The tradeoff between the Rails approach and the Consus approach is one of performance. I have a ton of respect for Konstantin and the work he’s done on Consus and other OO and OR databases available from his site. However, I sure the combined developer forces at major database vendors like Microsoft (and other DB companies) means SQL Server (and the like) will out perform Consus by a significant margin, especially on large scale databases. So if execution performance is your primary criteria, the Ruby on Rails approach is better (leaving aside discussion of the Ruby runtime itself). However, in the long run execution performance is much less important than developer productivity. So I believe that  for all the current interest in Rails, I think a Consus-style model will become dominant.

CLR Everywhere

Big news from the Game Developers Conference this week is the XNA Framework. From the press release:

The XNA Framework contains a custom implementation of the Microsoft® .NET Framework and new game-development-specific libraries designed to help game developers more easily create cross-platform games on Windows® and Xbox 360 using the highly productive C# programming language. Using the XNA Framework, game developers will benefit from the ability to re-use code and game assets in developing multiplatform titles, without sacrificing performance or flexibility.

So now I can the Xbox to the list of personal technology I can program, joining my phone, my TV, my server and my laptop all with C# or VB (VB plug brought to you by Brian and Erik who think I should to switch). I wonder if XNA Framework will support WPF?

BTW, I still want an easy way to program my house and my car, but I’m sure those are coming.

Where else should the CLR live?

The Annoying C# 3.0 “Unsupported Version” Dialog

I am sick and tired of the warning dialog box for the C# 3.0 preview. Every time you launch VS it pops up a dialog reading “This is an unsupported version of Microsoft Visual C# 3.0. As such many features may not work as expected.” You know, this isn’t my first time working with alpha or beta quality software. I’m also running WinFX Feb CTP, VB 9.0 Jan CTP and the Expression Interactive Designer March CTP. None of them feel the need to constantly remind me that they’re unsupported.

Who suddenly thought C# developers need hand holding?