Wizards and warriors, part two

In this series we’re exploring the problem “a player can use a weapon, a wizard is a kind of player, a staff is a kind of weapon, but a wizard can only use a staff”. The best solution we’ve come up with so far is to throw a conversion violation at runtime if the developer makes a mistake, which seems less than optimal.
Continue reading

Wizards and warriors, part one

A common problem I see in object-oriented design is:

  • A wizard is a kind of player.
  • A warrior is a kind of player.
  • A staff is a kind of weapon.
  • A sword is a kind of weapon.
  • A player has a weapon.

But before we get into the details, I just want to point out that I am not really talking about anything specific to the fantasy RPG genre here. Everything in this series applies equally well to Papers and Paychecks, but wizards and warriors are more fun to write about, so there you go.

OK, great, we have five bullet points so let’s write some classes without thinking about it! What could possibly go wrong?

Continue reading

DRY out your policies

Occasionally I’m asked to review code that has a lot of repetition in it. Like, for instance, someone is writing a function memoizer:

static Func<A, R> Memoize<A, R>(this Func<A, R> function)
{
  var cache = new Dictionary<A, R>();
  return argument =>
  {
    R result;
    if (!cache.TryGetValue(argument, out result))
    {
      result = function(argument);
      cache[argument] = result;
    }
    return result;
  };
}

And then they will write remarkably similar code for functions of two arguments, functions of three arguments, functions of four arguments, and so on. “I want my code to be DRY; how can I avoid repeating myself?” is what the developer asking for review usually says.

Continue reading

Long division, part two

This is a sequel to my 2009 post about division of long integers.

I am occasionally asked why this code produces a bizarre error message:

Console.WriteLine(Math.Round(i / 6000000000, 5));

Where i is an integer.

The error is:

The call is ambiguous between the following methods: 
'System.Math.Round(double, int)' and 'System.Math.Round(decimal, int)'

Um, what the heck? Continue reading

Defying gravity

No tech today, but some fun for Friday.

The 2015 Moisture Festival is over; if you’re not familiar with the festival, it’s a month-long celebration of old-timey and modern vaudeville, comedy, variety, burlesque and circus arts at multiple venues here in Seattle. Hundreds of artists come in from around the world, and often end up staying in my spare bedroom to cut down on their costs. This year I had the pleasure of spending a week with one of the world’s greatest jugglers, Niels Duinker, during the festival and I thought I’d post some links to his videos. When I was a college student I taught myself to juggle, but that was before all the great youtube tutorials that are now available.

Here is Niels on how to do three — start here if you’ve never juggled before.

Back in the day I got a few pretty solid four ball patterns going but I never managed to get more than eight throws with five, or six throws with three in one hand. Maybe I’ll give it another shot!

What is the unchecked keyword good for? Part two

Last time I explained why the designers of C# wanted to have both checked and unchecked arithmetic in C#: unchecked arithmetic is fast and dangerous, checked arithmetic is slightly slower but turns subtle, easy-to-miss mistakes into program-crashing exceptions. It seems clear why there is a “checked” keyword in C#, but since unchecked arithmetic is the default, why is there an “unchecked” keyword?

Continue reading