Tag Archives: C#

Closures in the real world

I’ve been saying for a long time that it’s cool to have a language with support for closures, but today for the first time I’ve hit a real-world problem where closures make life simpler, and where the language I’m using supports them sufficiently well.

Track Reordering diagram

Psonar have a web interface where you can reorder your music playlist by dragging tracks around. In the back end, this is implemented with a method that takes a list of tracks to move and a track that they should appear after, something like this (simplified example):

void ReorderPlaylist(Playlist targetPlaylist, List<int> trackIdsToMove, int targetTrackId)
{
   //...
}

What we’d like to do is iterate over the list with a for loop, and update the position of each track as we go. However, as soon as you start trying to write this you notice that you can’t update the position of track A without knowing whether tracks have been removed or inserted in front of it. Worse, when you recalculate the position of one of the tracks to be moved, you have to know where the target element ends up.

You don’t have the information you need when you’re half way through the for loop, but you do have it by the end of it. This is a typical case for lazy evaluation of some kind. Without lazy evaluation, the programmer has to decide which partial results can be calculated without dependencies, and to calculate these first. Defining the cases is difficult, and then you have to write runtime tests to categorise the data into the cases you can calculate. Worst of all, this produces code where the intent of the code is hard to figure out.

Lazy evaluation solves this problem. You can specify the position of each track not as an integer but as a function of an as-yet-unknown value. The functions depend on each other’s output values, but in a non-circular way. Specifically, many of the position functions depend on the position of the target element, which depends only on the choice of the set of tracks to move.

The way I coded this in C# (and I’m not convinced it was the neatest way), was roughly as follows:

Dictionary<int, Func<int, int>> newPositions = new Dictionary<int, Func<int, int>>();

int currentPosition = 0;
foreach (Track currentTrack in targetPlaylist.GetTracks())
{
   if (currentTrack.Id = targetTrackId)
   {
      newPositions[currentTrack.Id] =
         (targetPos => currentPosition);
   }
   else if (trackIdsToMove.Contains(currentTrack.Id))
   {
      newPositions[currentTrack.Id] =
         (targetPos => targetPos + tracksToMove.FindIndex(x => (x == currentTrack.Id)) + 1);
   }
   else
   {
      newPositions[currentTrack.Id] =
         delegate(int targetPos)
         {
            // Note call to function that doesn't exist yet
            int newTargetPos = newPositions[targetEntryId](0);

            if (currentPosition < newTargetPos)
            {
               return currentPosition;
            }
            else
            {
               return currentPosition + tracksToMove.Count;
            }
         };
   }
}

The position of each element is now a function of the position of the target element, which is a function that ignores its argument. Therefore we can calculate the target position first, then update each of the elements:

int newTargetPos = newPositions[targetElementId](0);
// Argument is ignored, we can pass anything

foreach (Track currentTrack in playlist.GetTracks())
{
   currentTrack.Position = newPositions[currentTrack.Id](newTargetPos);
}

I particularly liked the way that each of the branches in the main logic above is a simple statement of the position, as a human would think of it: “This track will be 3 places after the target track”, “This track will be at position 7, but 4 places further up if the target track ends up before position 7”, etc. This makes them relatively easy to check for correct logic.

Why it isn’t that simple

I lied about the above code. It’s written the way you’d like to see it written, but actually it’s wrong. The closures catch instances of variables that are modified within the loop, so the closures themselves get modified. To get round this you have to create local copies of all the variables you want to close over before you create the closure:

{
   int localPosition = currentPosition

   newPositions[currentTrack.Id] =
      (x => localPosition);
}

For the uninitiated, I’ll go into more detail about this in a later post.

Timeout errors in S3 connections using ThreeSharp

I had a bit of trouble using the ThreeSharp libraries to query S3, and I thought I’d share my experiences in case it was useful to anyone. I had a rather bizarre situation that the first 10 requests were always succeeding, and the 11th request was reliably timing out. It turned out to be due to the fact that ThreeSharp doesn’t close the HTTP request stream for you, unless you read the response data stream.

I was ignoring the response data stream for two reasons: Firstly, for an object copy request it doesn’t matter what the response is, provided the request is successful (and the HTTP status ought to be enough to assure that). Secondly, attempting to stream the response via StreamResponseToBytes() or one of the other methods actually causes an exception due to lack of necessary fields being set on the object.

It turned out that a sufficient (if slightly messy) solution is simply to explicitly close the DataStream:

ObjectCopyRequest copyRequest = new ObjectCopyRequest(sourceBucket, key, targetBucket, key);
ObjectCopyResponse copyResponse = query.ObjectCopy(copyRequest);
copyResponse.DataStream.Close();