17 07/10
13:37

Null parameter values are evil

One of the ideas I suggested in my last post was, What if C#:

prohibited passing null as method parameters

In this post I’ll discuss why I feel it’s a good thing, and why it’s entirely feasible to do.

So what the hell am I talking about when I say null parameter values are evil?  First up, I’m not saying nulls are evil.  Sir Tony Hoare famously called null references the billion dollar mistake.  He was talking about historically bad ideas at the time, and believes that we’d all be better off if “null” never existed.  I’m not convinced.  I feel nulls have a place and a special meaning, just like void has a meaning.

So I’m focusing on a smaller idea: null parameter passing.  I consider this an anti-pattern:

R Method(A a, B b)
{
    if(a == null) throw ArgumentNullException("a");
    if(a == null) throw ArgumentNullException("b");

    // ...
}

There are a few reasons why I’m not happy with this.

  • We rely on human code reviews for ensuring this (anti)pattern is always followed.  That means there’s a risk it’ll be missed.
  • It’s boilerplate.  Our code would be much cleaner and easier to read if we didn’t have to follow this.
  • This is just one way of a variety for null checking: for example, we can also use
Debug.Assert(a != null, String.Format(Messages.CannotBeNull, "a"));

So I’m suggesting we move the job of generating this code to the compiler, so that the above example code  can now be written as

R Method(A a, B b)
{

    // a and b are definitely not null if this point is reached
    // ...
}

Calling code looks like this:

a = null;
b = null; 
var r = obj.Method(a, b);  // throws an ArgumentNullException

So, it’s technically possible–but the remaining question is this: are there any valid use cases for null method parameter values?  The answer as far as I can tell is no.  The most obvious use for null parameters is with method overloading:

R Method(A a, B b)
{
    // do stuff
}

R Method(A a)
{
    return Method(a, null);
}

This can be refactored as:

R Method(A a, B b)
{
    DoSomethingWithA(a);
    DoSomethingWithB(b);
    DoSomethingWithAandB(a, b);
}

R Method(A a)
{
   DoSomethingWithA(a);
   // since a is passed in alone, we can assume that its value
   // is independent of B, so DoSomethingWithAandB() does not
   // need to be called, or can be called with b's previous
   // value. 
}

This is actually a neater design anyway, because it requires splitting out the independent processing of the variables.  I’ve come across one situation that’s a bit ugly: when you need to call 3rd party libraries that accept and expect null parameters.  For example:

public R OtherMethod(T t)
{
_thirdPartyLibrary.OtherMethod(t);   // what to do if null is a valid value?
}

This is especially difficult if the connection to the third party library requires set up and disposing, for example:

public R OtherMethod(T t)

{
    using(var thirdPartyLibrary = new ThirdPartyLibrary())
    {
        thirdPartyLibrary.OtherMethod(t);
    }
}

This would necessarily become:

public R OtherMethod(T t)
{
    using(var thirdPartyLibrary = new ThirdPartyLibrary())
    {
        thirdPartyLibrary.OtherMethod(t);
    }
}
// this overload is used for null values
public R OtherMethod()
{
    using( var thirdPartyLibrary = new ThirdPartyLibrary())
    {
        thirdPartyLibrary.OtherMethod(null);   // passing null is fine
                                               // because this component
                                               // wasn't built with our
                                               // amazing compilation technique
    }
}

Yes, it’s our old friend repeated code – but I’d happily put up with this for the sake of the extra precondition checking I’d get for free.

How to implement this is the next question: one option would be a form of IL injection, like aspect-oriented programming.  Another option would be an entirely new compiler, with not just this language modification, but all the other changes I suggested in my previous post.   That would be a cool research project!

If you’re still following along, there are a couple of obvious questions that come up at this point:

  1. What about .NET 4 code contracts?
  2. What about F#?

Both valid points, and yes both solve this issue, but unfortunately I don’t like either solution.  Code contracts is again more boilerplate code – it just shifts the form of the code written.  I believe that for software engineering to take the next step, we need to move towards less code and more component-based design.  F#, on the other hand, solves it by dissallowing nulls entirely, but I think F# is an ugly language.  Spec# was on the right track, but that’s really what code contracts have become in C#.

I’m always interested in projects making the leap to non-nullable types.  I think null really helps, in particular returning null from methods, either as the return value or an out/ref parameter.  The TryGetValue pattern is an awesome example of this.  It’s a useful idiom because you can do a Has and a Get in one atomic operation.  You need null in this case–it just doesn’t make sense to return any value other than null, if Has is false.  Of course, proponents of non-nullable types would argue that there are other ways of achieving the same thing–but that’s a discussion for another day…

15 07/10
07:06

What if….?

What if C#….

  • had no properties?
  • had only private fields?
  • fields were readonly by default?
  • had no mutable static fields?
  • had no static methods or static classes?
  • prohibited passing null as method parameters?
  • integrated specs/test with code, in the same file?
  • only allowed one class per file?
  • prohibited nested classes?
  • had syntax distinguishing between class dependencies and notifications with special syntax?
  • enforced command-query separation from methods?

Some of these ideas are almost unworkable, some are fundamental to the cause and some are just “my style”.  In a future post I’ll go over each in detail and see how they can be implemented–maybe I’ll just hack a few FxCop rules together and be done with it.

27 06/10
17:41

Brighton

Tags: ,

Yesterday, me and the gang headed to Brighton beach for a barbecue. We’d actually planned to go to Oxford but, as is often the case with us, one thing lead to another and we headed south instead.

Completely unexpected and brilliant fun–we arrived at 5pm, the sun still strong, just a light breeze and a quiet sea. The beach wasn’t packed but it was busy, with lots of groups barbecuing, just like us. Some had tiny disposable set-ups (us), others seemed to have mini bomfires on the go.

I can’t help but imagine doing this every weekend evening: it’s an appealing way of life. For now I’m stuck in London, City of Stress, but I can certainly see myself making a move to Brighton in the not so distant future.

25 06/10
19:53

A picture’s worth a thousand words. But diagrams are difficult to draw…

Nightmare! Earlier this week at work, I wasted a good few hours attempting to draw a diagram. “Wasted” because, shock horror, it wasn’t a very successful attempt. The awful truth is that I can’t draw to save my life.

I’d love to blame the tools, but since I’m trying to be a better workman, I won’t do that. The tool in question is Microsoft PowerPoint. The scene is my lounge: me with my trusty laptop, alongside a strong pot of coffee for moral support. The task is this:

Explain your six-month product vision to your team, your boss and your customers. Leave no one confused, and everyone enlightened.

Let me go back a bit and fill in some of the back-story. The software product my team develops is great and all, but it has a knack for leaving our users in tears. There are various “product features” (yep, you guessed it, I’m using that term loosely) that hinder our users in their day-to-day jobs. So, I’m hosting a conference call for some of our disgruntled users, and during this call I’ll describe how we plan to fix it all.

Feature, n. A bug that has been documented.

Because of the scale of the task, it struck me that a diagram was the way to tackle it. If I were to do it in speech, I’d want to cover:

  • The current problems we’re facing
  • The proposed changes to the architecture
  • Reasons why it simplifies the product
  • Some blurb about how this is the right approach to take. In other words, plead for approval.

Now I’m sure this can all be said in a diagram, but I sure as hell haven’t figured out how. I needed a sort of process diagram, showing the various nouns and connecting them with verbs—a user submits a request to the build server which kicks off this automation task that reports to a database—but when I started it just looked crap. A bit like this.

An epic failure of a PowerPoint diagram

The concise diagram I had in my head ended up as a series of soulless boxes and arrows, all very bland and yes, I’m too ashamed to show you the end result.

Am I the only one with this problem? I’d like to think not. On the day of the conference call, two things happened:

  1. I decided against using the presentation and just talked instead.
  2. I questioned my teammates if any of them could teach me how to make awesome PowerPoint diagrams.

One of the answers I got was you can’t; just stick with text. The other answer I got was do it the old-fashioned way, with a paper and a pen. That struck me and a damn good idea: one quick visit to Waterstone’s and I’ve now got this sitting beside me:

What fun awaits?

I haven’t made an attempt yet to draw anything, but I’ll keep you posted…

05 06/10
17:10

Sunshine Retrospective

Yesterday our team ended the week with an outdoor retrospective. June has started off with awesome sunshine and warmth here in London, so getting out of the office seemed like the right thing to do. There’s not much to love in the office anyway, so who wouldn’t want to escape to the fresh air? Come to think of it, I should work “from home” more often and then head to the park with my laptop…

Anyway: back to the original point. We found a wide bench and gathered round, some standing, some sitting. It was all very haphazard and quite beanbaggy. As it turned out, the outdoor setting and relaxed atmosphere made the meeting pretty productive. We’d had a fairly hectic iteration; debates were heated, the pace relentless and design shortcuts the norm. By the end a lot of nerves were frayed. I think it’s fair to say that we all expected a tense and painful retrospective. But in the event, no one lost their cool, and the tempo of the discussion stayed fairly constant and lively. We rattled through a whole spectrum of issues and not once did it turn personal.

Can we draw any conclusions from this? I’m fairly convinced that the setting played an important role. For sure, tension dissipated because the area was without walls. Having nature around us kept things in perspective: it’s not all a life-and-death situation. It’s only software!