Insights and outlooks on software development

S'true

NUnit and lambdas

Saturday, November 29, 2008 by Thomas L

So as you may have noticed, I really love lambdas. Having the possibility to write code like the row below makes my code more readable.

List<Person> people = peopleRepository.FindAllByName("Thomas");
int totalAge = people.Sum(person => person.Age);

So I would like to use lambdas and list iterations to assert things in NUnit, e.g. like this:

Assert.Contains(people,
  person => person.FirstName == "Thomas" && person.LastName == "Lundström",
  "The list should contain Thomas Lundström");

That way it's way much more readable than how I have to do to get the same functionality today:

Assert.AreEqual(1,
  people.FindAll(person => person.FirstName == "Thomas" &&
    person.LastName == "Lundström").Count,
  "The list should contain Thomas Lundström");

I think it would be a fun project to implement it.

Technorati Tags: ,,,,

On Joel on Software and perfect marketing

Friday, November 28, 2008 by Thomas L

Joel Spolsky posted a really interesting article some time ago. He gives a tip about a way to focus your development and says "oh, by the way, we have a new feature in our Copilot product". That's a ingenious way to push market information to the readers of his blog. The community who reads the blog feels that they have won something on reading the tip, and by a coincidence they learn that Joel now has a new Copilot release. So I'm not so sure that Seth Godin is the only "marketing guru extraordinaire" over there.

Technorati Tags: ,

On migrations API:s in .NET

by Thomas L

So I absolutely love Rails' Migrations. The functionality is kick-ass, and the API is super-nice. See for yourselves:

create_table :users do |table|
  table.column :name, :string
  table.column :login,  :string, :null => false
  table.column :password, :string, :limit => 32, :null => false
  table.column :email, :string       
end

I'd like to have this in the .NET land as well, and with an as nice API as well. There is the Machine.Migrations by Jacob Lewallen with an API that looks like this:

Schema.AddTable("users", new Column[] {  
  new Column("Id", typeof(Int32), 4, true, false),  
  new Column("Name", typeof (string), 64, false, false),  
  new Column("Email", typeof (string), 64, false, false),  
  new Column("Login", typeof (string), 64, false, false),  
  new Column("Password", typeof (string), 64, false, false),  
}); 

(The code is blatantly stolen from a blog post of Jacob's.)

There is also the migratordotnet project which has a similar API, I actually like this API a tiny bit more than the Machine.Migrations one, but it's more or less the same. But the main thing is that the API for defining the migrations is somewhat hard to read, and readability is an extremely important property of code.

What I'd like to have is a API looking somewhat like this:

Database.AddTable("Users").WithColumns(user => Is.String.WithSize(64), userId => Is.Int.WithSize(32));

This would actually be implementable in c#. I haven't done anything to make this API work with Machine.Migrations or migratordotnet as I'm only playing with a thought as of now, but it's quite fun to see how much you can do with closures.

Fluent interfaces by lambdas in C#

by Thomas L

This thursday and friday, I've been in the lovely small town of Karlskrona and attended a Domain-Driven Design course/seminar with Jimmy Nilsson, arranged by my employer, Softhouse. One part of the workshop was on fluent interfaces; and I found out that it's actually quite unknown that you can do stuff like this in C# (I know, it's not the best of examples, but I'm writing this on a friday night.)

Vodka v = new Vodka(4.centiliters());
Centiliter c = v.Centiliters;
Assert.AreEqual(4, c.number);

Notice the "4.centiliters" construct. To make it work I use an extension method on int to construct the Centiliter class:

public static Centiliter centiliters(this int numberOfCentiliters)
{
  return new Centiliter(numberOfCentiliters);
}

This would of course look even better in ruby, its dynamic nature lends itself quite well to building fluent interfaces. But some parts of building fluent interfaces are actually possible to steal from ruby. Like for instance the idiomatic block example:

5.times do
  puts "hello world!"
end

...is possible to implement in C#:

5.Times(() => Console.WriteLine("hello world!"));

The syntax is quite much worse than ruby's; it has too much of noise in the form of parantheses, semi colons and the rocket operator (" => "), but the C# team has definitely made one step towards a more usable language as a whole by adding the lambda construct to the language. I'd love the possibility to remove "() =>" from the lambda above (please, pretty please, with sugar on top, Anders?), since then the syntax would be

5.Times(Console.WriteLine("hello world!"));

The extension method I use to get the syntax above looks like this:

public static void Times(this int number, Action block)
{
  for (int i = 0; i < number; i++)
    block();
}

I know that the examples above are quite unusable, but there are ideas up there that actually is usable; the Machine.Specifications (or MSpec for short) uses lambdas to do its thing. And the one big part that is intimidating everyone new to MSpec is the "() =>" syntax. If we could get rid of that, it'd be easier to introduce BDD to the .NET community.

Technorati Tags: ,,,

Free book about css

Thursday, November 20, 2008 by Thomas L

See http://twitaway.aws.sitepoint.com/ for more information. Open for another 12 days...

(I like the way they use aws for this one-time offer that has the potential for slashdotting the regular sitepoint site.)

Amazon cloudfront - Akamai for the rest of us

Wednesday, November 19, 2008 by Thomas L

We live in an interesting time: http://aws.amazon.com/cloudfront

This is getting really interesting. Amazon's business model for their AWS product suite seems to be less and less about renting out excess space, but instead it's more and more about supplying different sets of scaling resources at a flexible cost.

Øredev thoughts

by Thomas L

Today I've been to the Øredev conference, and these are some of my comments from today:

  • I really need to make a (proper) release plan for the project I'm currently working in, based on the team's current velocity
  • I have to take a step back and thinking about how my project actually can deliver value in the Lean sense; perhaps we should release it to production soon?
  • Value stream mapping - a nice tool for doing the above
  • Eric Evans talked about the "big rewrite" and how it won't be released according to plan (does it ever)
  • Instead of doing the big rewrite and starting with porting the basic functionality, it's perhaps better to start with the differentiating features, and creating an integration layer to the rest of the functionality

And; how do I do the following:

  • Snap a photo with my Windows Mobile phone
  • Write a comment
  • The photo is GPS geotagged and uploaded to flickr/amazon/another host
  • The comment is posted to twitter together with the image link

All of the above should be done in an instant, with one or two button presses.

Please say that there already is an app for this.

Technorati Tags: ,,,,

Writing good tests

by Thomas L

Colin Jack has a couple of blog posts on testing using the BDD-ish context/specification type of tests. Check them out!

I often like to write my (NUnit) tests like so:

namespace BlogpostBehaviour
{
  [TestFixture]
  public class AfterSavingABlogPost
  {

    private BlogRepository _blogRepository;

    [SetUp]
    public void SetUp()
    {
      _blogRepository = new BlogRepository();
      Blog blog = new Blog()
      {
        Id = 12,
        Title = "My new post",
        Text = "Some text with a specific word"
      };
      _blogRepository.Save(blog);
    }

    [Test]
    public void ShouldBeAbleToSearchForBlogByContents()
    {
      Assert.AreEqual(blog.Id, _blogRepository.Search("specific")[0].Blog.Id);
    }

    //more assertions...
  }
}

This way I can easily use the normal toolchain with NUnit and such, and have new developers grasping the test setup, but still tricking the old-school unit test developers into thinking context/spec.

Technorati Tags: ,,,,