Entries from August 2008 ↓

Time, time, time

Time is a funny thing, a day can drag out and feel like an eternity, but a year can pass in a blink of an eye.

I’m about 8,395 days old today, that’s roughly 201,480 rotations of the hour hand of your clock. Remember how long it takes for that hour hand to drip by while you’re in yet another boring meeting? I’ve had over 201 thousand of them.

That all equates to 23 years old, which isn’t too bad I suppose.

It’s not often I talk about myself. I have a lot of opinions, but I generally keep me to myself. On this occasion I’m going to give myself a pat on the back.

I’m pretty proud of myself.

I have no qualifications, I have no A-levels, and only a few GCSEs. I am completely self-taught.

One thing that I’ve learnt is that only you know yourself. If somebody says you can’t do something, fuck them. Who are they to tell you what you can and can’t do? Prove them wrong.

I was told that programming is hard, and it’s not something you can learn in your bedroom any more. I was told I’d not be earning more than £14,000 by the time I was 20. I was told there was no chance I could get a job without any formal qualifications. Two jobs down the line, too many languages to list, and more money than sense - I think I proved them all wrong.

The best thing you can do for yourself is to learn how to learn. It’s the one thing they don’t teach you in school. Since I learnt how to learn, I’ve gained so much knowledge.

Don’t concern yourself with the details, learn the techniques, learn the principals. It can be mistaken for arrogance, but I’m so confident in my ability to learn, that I can safely say that I can use any programming language, any operating system, any technology, ever invented and ever to be invented.

I am not scared of change, of new technologies, and I’m not afraid of being left behind. I can adapt, because I can learn.

It’s been a crazy ride so far, I look forward to what the next few years bring.

Introducing Fluent NHibernate

A couple of people have already covered this already, specifically Bobby Johnson, Matt Hinze, and Zachariah Young. I figure I should say something on it anyway.

I’ve adopted a project from Jeremy Miller that I think has the potential to be a really useful tool. It’s called Fluent NHibernate, and it’s primarily a fluent API for mapping classes with NHibernate.

We’re all well aware how awesome NHibernate is, but I think we all also have a bit of a dislike for the amount of XML you need to write to get your classes mapped; not only that, but also how the mappings are distinctly separate from the rest of your application. They’re often neglected and untested. One of the core tenets of the project is that we need a more succinct, readable, and testable way of writing your mappings.

The API

Take the following simple hbm file:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
    namespace="Eg" assembly="Eg">

    <class name="Customer" table="Customers">
        <id name="ID">
            <generator class="identity" />
        </id>

        <property name="Name" />
        <property name="Credit" />

        <bag name="Products" table="Products">
            <key column="CustomerID"/>
            <one-to-many class="Eg.Product, Eg"/>
        </bag>

        <component name="Address" class="Eg.Address, Eg">
            <property name="AddressLine1" />
            <property name="AddressLine2" />
            <property name="CityName" />
            <property name="CountryName" />
        </component>
    </class>
</hibernate-mapping>

Then compare it to the same mapping, created using the fluent API:

public CustomerMap : ClassMap<Customer>
{
  public CustomerMap()
  {
    Id(x => x.ID);
    Map(x => x.Name);
    Map(x => x.Credit);
    HasMany<Product>(x => x.Products)
      .AsBag();
    Component<Address>(x => x.Address, m =>
    {
        m.Map(x => x.AddressLine1);
        m.Map(x => x.AddressLine2);
        m.Map(x => x.CityName);
        m.Map(x => x.CountryName);
    });
  }
}

Firstly, you’ll note that there is a marginal reduction in lines of code, but that’s not what we’re particularly striving for. Instead we’re intent on reducing the verbosity and noise of the code. This manifests itself in a convention over configuration design for the API, where we choose the most common setups and use those as the default. For example with the id element in the hbm file, you’re required to specify what the generator type is; however, in our fluent API we check the type of your identity property and decide what generator we should use. Int’s and longs default to identity, while GUIDs use the guid.comb generator. You can change these explicitly, but when you are using the default, it greatly reduces the verbosity of your mapping.

Testability

Another one of our goals is to make your mappings more robust. I imagine most people have had the problem where you’ve renamed a property and not updated the mapping file; due to there being no compile time validation, the only way to catch these mistakes are at run time (hopefully you had tests to cover that!). With the way our API is designed, you use the actual properties on your classes to create the mapping, so there’s nothing to forget. If you rename a property, your IDE will either rename the property in the mapping, or fail at compilation.

We also want to help you verify that your mappings are set up properly, not just syntactically valid. So to make your integration tests a bit easier, we’re providing an API for testing your mappings.

[Test]
public void VerifyCustomerSaves()
{
    new PersistenceSpecification<Customer>()
        .CheckProperty(x => x.Name, "James Gregory")
        .CheckProperty(x => x.Age, 22)
        .VerifyTheMappings();
}

Behind the scenes the PersistenceSpecification creates an instance of your entity, then populates it with the values you specify through the CheckProperty method. This entity is then saved to the database, then reloaded through a separate connection. The returned entity is then compared to the one originally saved, and any differences fail the test. It’s a fairly standard integration test, except we’ve taken the time to write all the wiring up that needs to be done, so you don’t have to.

The Framework

We’re working towards our first official release, which will have a fairly solid implementation of the API. Once that’s out in the wild, we’re going to focus on our Framework.

Our framework is a layer that sits on-top of the API to provide an even better experience. We’re looking to integrate with your favorite container, which will reduce the code you need to write to integrate NHibernate into your system. Then we’re going to tackle extensible conventions, which will allow you to specify your own implied conventions for your application. For example, if you’re always going to call your identifier “ID”, then why should you have to specify it every time? You shouldn’t!

Development is progressing at a nice pace, and I expect we’ll be able to get our first release out within the next few weeks. The testing API hasn’t been kept quite as up to date as the main API, but we’re working on that too. It’s open-source, so suggestions and patches are welcome.

Latest on BooLangStudio

It’s been a long time since I’ve written anything about BooLangStudio. Let me assure you that the development is still very much underway, and we’re steadily working towards our first release.

To fill you in a bit on what’s been going on. Jeffery Olson has completely rewritten the syntax highlighting to use the more flexible Boo.Pegs lexer, which allows us to overcome some of the obstacles we were facing with the traditional Boo lexer. There were limitations to what we could do with the traditional lexer, without modifying the Boo source. This was leading us down a road we weren’t keen on, one of maintaining a fork of the Boo source that contained our specific changes. With the move to the Boo.Pegs lexer, we’re free of this scenario!

Justin Chase has been tackling various issues all over the place. Several related to the build process, specifically how the Boo binaries are located on your machine, which has been a bit of a problem when there’s multiple developers working on a project whom both have Boo installed in a different location. He’s also been spiffing up the interface by adding some much needed icons to the projects.

Torkel Ödegaard has been working various issues throughout the project. He’s created a properties dialog for the project which allows you to alter the usual settings for your project, assembly name, default namespace etc… He also managed to get debugging working, which is awesome.

Then there’s me, I’ve been working on the intellisense capabilities. We’ve had intellisense support from day one, but it’s never been very extensive. For a long time it only worked on the current file you had open.

The entire solution is now processed behind-the-scenes to provide intellisense. Import statements are now recognised and imported types appear in the local scope intellisense. Any assemblies or projects that are referenced have their top-level types and namespaces included in the intellisense too.

Additionally I’ve been working on improving the method suggestion logic, which was initially very flakey. It boils down to being able to transform the current line into the desired type, which can be difficult in certain cases (StringBuilder().Append("Hello world").ToString(). for example).

I believe that about covers what we’ve been upto lately. Our biggest problem currently is that most of these features are implemented in separate branches, and haven’t yet been merged into our central repository. We’re working on this, and I reckon once we’ve done that we’ll be looking at doing a release.