Fluent Languages

3 minutes read

Originally posted on: http://geekswithblogs.net/jolson/archive/2008/06/02/fluent-languages.aspx

The first time I saw some talk about this "movement", it was Martin Fowler discussing "Fluent Interfaces".

An example Martin gives is the idea of time intervals. Here's how one might declare an interval today (in Java):

TimePoint fiveOClock, sixOClock;
...
TimeInterval meetingTime = new TimeInterval(fiveOClock, sixOClock);

Here's how one might to do the same with a fluent interface (anybody who writes Ruby code should recognize this type of programming):

TimeInterval meetingTime = fiveOClock.until(sixOClock);

Like Jeff Atwood, I haven't exactly been a fan of fluent languages in the past (pre-LINQ). I honestly never saw the point in them (and I thought all the object syntax got in the way of what was being done). My mind has definitely changed though. As of late, you could say I'm on a bit of a "fluent languages kick."

LINQ, of course, had a play in this, as did the introduction of lambda expressions. But, it was really seeing two specific libraries that started to get me excited about fluent languages: Moq and NInject. When you compare fluent languages to Regular Expressions and SQL, I can imagine how it's hard to understand the benefit. But when you have a library that reads wonderfully out loud and "fits" an existing problem in order to make it easier to understand, I think it's A Great Thing.

Mocking is a topic I've been pretty passionate about in the past. Even with that passion, there was one thing I didn't like about the libraries back then: breaking changes when refactoring. A lot of mocking frameworks in the pre-.NET 2.0 days were string based. If you wanted to mock an aspect about a method, you put the name of the method in a string and pass that somewhere. Well, the second I renamed that method, BAM!, my unit test would stop passing (of course). Yes, the unit test caught it, but it was still highly annoying. Enter Moq.

Moq leverages lambda expressions to be able to determine what should be mocked. I think the solution Daniel Cazzulino has used is awesome. Let's look at some Moq code to mock some code:

var mock = new Mock<ILoveThisFramework>();

// WOW! No record/reply weirdness?! :)
mock.Expect(framework => framework.ShouldDownload(It.IsAny<Version>()))
    .Callback((Version version) => 
        Console.WriteLine("Someone wanted version {0}!!!", version))
    .Returns(true)
    .AtMostOnce();

I love how this reads. I think the trick behind groking fluent languages is reading them aloud. Go ahead, go back and read that out loud (just ignore the laughing coworkers, we'll get back at them later :P). Not only does this read very well, but if I refactor/rename the "ShouldDownload" method in Visual Studio, the use of that method in my mocking code will be updated as well.

The other fluent language that got me excited was the work Nate Kohari is doing on NInject. Assuming you are familiar with Dependency Injection, the best way to understand NInject is to drive write into code:

class Samurai {
  private IWeapon _weapon;

  [Inject]
  public Samurai(IWeapon weapon) {
    _weapon = weapon;
  }

  public void Attack(string target) {
    _weapon.Hit(target);
  }
}

So I have my injection point defined in my Samurai class. My Samurai is going to need an IWeapon. So how do we bind these two together with NInject?

Bind<IWeapon>().To<Sword>();

Once again, read this out loud. It literally reads like "Bind IWeapon to Sword". I just love that (your mileage may vary :P).

One of the things that bothered me about fluent languages in the past was that people would say "they're so great, they read just like our own language". Well, we've been down that route before, and I definitely wouldn't consider myself a fan of COBOL! So why the love for fluent languages?

One of the problems with spoken languages when it comes to programming is that spoken languages are very ambiguous and allow many meanings for a single word or phrase. In order to avoid that problem, I think COBOL became too obtuse. To be exact enough for a programming language while being solely "written language"-esque, syntax becomes annoyingly long.

The reason I like this new trend of fluent languages in .NET is that it introduces the readability of spoken languages while avoiding the obtrusiveness of languages like COBOL. To me, it's like having my cake and eating it too.

Geek Fact of the Day: Do you know the origin of the term "grok"? The term comes from Robert A. Heinlein's book Stranger In A Strange Land.

Updated:

Leave a Comment