Saturday, October 25, 2008

Amazon EC2

Amazon's Elastic Cloud Compute (EC2) is a nice idea, but it's important not to overlook the "elastic" in the name. If there's an obvious temporal pattern to your service's usage (examples: 1. it could easily consume 100% CPU of 5 machines between 7 am and 11 am, but slow to a dawdle for the rest of the day, or 2. a large system could lie unused on weekends and holidays), and you design your application with parallelism in mind, this could be a cost effective strategy for hosting the service. As they bill you per "instance-hour" (loosely defined as an "instance" available for all - or part of - an hour), an available _idle_ instance will cost the same in a month as an available _fully-utilised_ instance. Costs start to fall as soon as you turn off your under-utilised instances dynamicall; which is something you can't yet do when renting physical space in a data center (AFAIK).

For small business without the need for elasticity (note: does that spell "unsuccessful"?), I'm not convinced it would be as cost effective as renting some tin in a data center and running multiple virtualized instances on some technology like Hyper-V, ESX or Xen.

Wednesday, October 22, 2008

Assert.That(actual, Is.EqualTo(expected).Within(tolerance))

New to NUnit 2.4 back in March 2007:

using NUnit.Framework.SyntaxHelpers;

I really like this idea as it can make some unit test code much more legible!

Saturday, October 18, 2008

Language Optimization Observations

Progamming languages are becoming prolific. Most recently the trend of domain specific languages has emerged. On any given project, multiple languages will be employed (to varying degrees of success). Their design can be influenced by many factors. Some - if not most - languages enable one to succinctly and elegantly define a solution to a problem, speeding up initial development and subsequent modifications. However, as the languages get more abstract they appear to get slower and slower to run. Maybe it's that they're solving bigger problems? Maybe it's that their runtime environments have been designed for the general case, and literally "karpullions" of CPU cycles are being wasted maintaining state in which we [for a given application] are not interested. The smart money is on over-generalized and sometimes poorly implemented runtime environments.

Thursday, October 16, 2008

Duct Typing

defn: A portmanteau of duck-typing and duct-taping. Used to describe the effects of defining .NET extension methods in your own code to give existing objects "new" functionality.

Closures in C#

If I'm using the wrong terminology: sorry; you lose. The C# compiler is a wonderful thing. Among it's many gifts to us are iterator blocks (think: yield return) and anonymous methods (think: delegate literals). Neither of these constructs has a direct parallel in MSIL, the common intermediate language to which all C# code is compiled. Instead the C# compiler defines new types to encapsulate their behaviours.

Iterator Blocks

An iterator block becomes a state machine; a disposable enumerator. Code defined in C# as this:

public static IEnumerable PublicEnumerable()
{
yield return 1;
yield return 2;
yield return 3;
}

is compiled down to the MSIL equivalent of this:

public static IEnumerable PublicEnumerable()
{
return new d__0(-2);
}

The class d__0 is a closure, and if we take a peek in Reflector we see the following definition:

[CompilerGenerated]
private sealed class d__0 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable
{
// Fields
private int <>1__state;
private int <>2__current;

// Methods
[DebuggerHidden]
public d__0(int <>1__state);
private bool MoveNext();
[DebuggerHidden]
IEnumerator IEnumerable.GetEnumerator();
[DebuggerHidden]
IEnumerator IEnumerable.GetEnumerator();
[DebuggerHidden]
void IEnumerator.Reset();
void IDisposable.Dispose();

// Properties
int IEnumerator.Current { [DebuggerHidden] get; }
object IEnumerator.Current { [DebuggerHidden] get; }
}

The object instance can be returned to the caller of PublicEnumerable where it will behave like the iterator block we know and love.

Anonymous Methods

Anonymous methods can access local variables defined in the same scope. When a delegate literal contains a reference to a method local variable (see: i in the following example):

public static void DelegateLiteralTest()
{
Int32 i = 5;
Action add = delegate(Int32 value) { i += value; };
Console.WriteLine(i);
add(1);
Console.WriteLine(i);
add(2);
Console.WriteLine(i);
}

the C# compiler generates a new type (closure) that resembles the following:

[CompilerGenerated]
private sealed class <>c__DisplayClass1
{
// Fields
public int i;

// Methods
public <>c__DisplayClass1();
public void b__0(int value);
}

Notice how the local variable is now scoped to the instance of the closure, and how it's an instance of this closure that's used inside the method:

public static void DelegateLiteralTest()
{
<>c__DisplayClass1 __closure = new <>c__DisplayClass1();
__closure.i = 5;
Console.WriteLine(__closure.i);
__cloure.b__0(1);
Console.WriteLine(__closure.i);
__closure.b__0(2);
Console.WriteLine(__closure.i);
}

I think this is pretty darn cool.

Sunday, October 12, 2008

Singleton Pattern vs. C# Static Class

At the most basic level, both constructs are useful in limiting the number of instances of an object that can be created. There are numerous subtle differences at the implementation level, but the single biggest difference is at an object-oriented level: static classes do not support polymorphism. This stems from a combination of factors at the language level; in short, a static class cannot inherit from a base class (abstract or concrete) nor can it implement any interface methods. Conversely, you can neither define static virtual methods on a class, nor can you define them on an interface. So, if you're ever using dependency injection [insert link here] - a technique that relies heavily on polymorphism - you will likely find that static classes will be inadequate, limiting, and plain frustrating.

There are a number of other runtime level differences, but these are all secondary to the polymorphism issue. The simplest is that a static class can never be instantiated, and all methods are executed against the type instance. Contrast this with the singleton, of which exactly one instance is created, and where methods are executed against that instance.

Next time you're involved in object design and you come across a potential application for the singleton pattern, don't forget this posting!

Monday, October 06, 2008

Delegate vs. Event

What's the difference between a delegate and an event in C#, you ask? An event provides better encapsulation (read: a more object orientated approach) while a delegate is "merely" a immutable multicast type-safe function pointer. In other words, an event is an encapsulated delegate, where only the += and -= functions are non-private. That means that although we can add new subscribers to the event from another class, we cannot invoke it. The add and remove accessors are the only members to retain the event's declared access (e.g. public).

It's easier to explain delegates first.

Delegates


  • Function pointer: a delegate acts as a layer of indirection allowing references to methods to be passed between objects. The target methods are invoked when the delegate is invoked.
  • Type-safe: unlike function pointers in C++, a delegate knows the type of the target object, and the signature of the target method.
  • Multicast: a delegate maintains a list of methods; it isn't limited to invoking just one
  • Immutable: delegate instances - like strings - cannot be changed. When you add/remove another target method to/from a delegate instance, you're really creating a completely new delegate instance with a superset/subset of target methods.

    A delegate example


    Define the delegate type, or use one of the many predefined types shipped with the FCL.
    public delegate void Function(string value);
    Define the target methods that we can call. These will have to conform to the signature of the chosen delegate type.

    static void WriteOut(string value)
    {
    Console.Out.WriteLine(value);
    }

    static void WriteError(object value)
    {
    Console.Error.WriteLine(value);
    }

    Define a class with a public delegate field (bad object-oriented encapsulation, but it's just for the purpose of example).

    class DF
    {
    public Function function;
    }

    Construct a new instance of this class, add a couple of target methods and invoke them through the delegate:

    DF df = new DF();
    df.function += new Function(WriteOut);
    df.function += new Function(WriteError);
    df.function("Delegate");


    Events


    An event is a construct that is functionally similar to a delegate, but provides more encapsulation. Specifically, adding/removing target methods is given the accessibility of the event (e.g. public/protected/internal). Everything else is given the accessibility modifier of "private". This allows subscribers to be notified of an event, but not to trigger it themselves.

    An event example


    Again, pick a delegate type from the FCL or define your own. For this example, I will reuse the Function delegate type, and the two Function methods defined above.
    Define a class with an Event:

    class EF
    {
    public event Function function;
    }

    Construct a new instance of this class, add a couple of target methods:

    EF ef = new EF();
    ef.function += new Function(WriteOut);
    ef.function += new Function(WriteError);

    Because of the encapsulation, we cannot call the following method from outside the declaring type:

    //ef.function("Event"); // ... can only appear on the left hand side of += or -= (unless used from within the event's declaring type)


    A good technical resource:
    Difference between a delegate and an event.
  • Wednesday, October 01, 2008

    Indispensable Software Engineering Tools for .NET

    Requirements
    =
    JIRA: rudimentary but ok, not so great for managing project plans
    -
    Source Control
    =
    Subversion: all check-ins must have a reference back to the original requirement.
    Everything included in the release must be held in the versioned repository.
    Everything means everything... environment specific config files.
    (Don't store usernames and passwords in source control, but that's ok because you didn't hard code them into your configuration anyway, did you!?)
    -
    Build
    =
    CruiseControl.NET:
    > get latest from source control, tag so that the build can be repeated.
    > ensure compiled assemblies are versioned so they can be traced back to the build.
    > build, run unit tests and other code metric tools.
    Code Metric Tools:
    >FxCop
    >NUnit
    >NCover
    >anything for cyclomatic complexity?
    Post Build
    =
    FishEye: great for seeing all metrics, committed changes etc. Useful when you need to see what changes went into a build.
    -