Picking the Right Tool for the Job

When your only tool is a hammer, every problem looks like a nail.
– Abraham Maslow

I recently organized a coding dojo where we solved the bowling kata. In short, the bowling kata is about programming a score-keeper for a game of ten-pin bowling. At any given time during the game, the score-keeper must be able to yield the current score for all players. Additionally, the program must be able to tell which player is the current player, in order to assign scores correctly.

I began solving the kata in my programming language of choice, C#. The solution naturally converged to an imperative state machine, incrementing scores as the game progressed. This lead to entangled code with many special cases, struggling with the tracking of arbitrary strikes and spares.

Then I realized that the problem is in fact two-fold. One part of the problem is to keep track of which player knocks over which pins, while the other part is the actual calculation of the scores. Given a sequence of numbers representing the amount of pins knocked over, the score can be calculated as a relatively simple function. At this point, I reached for my .NET toolbox and picked the tool best suited for writing functional code, F#.

module BowlingCalculator

[<CompiledNameAttribute("CalculateScore")>]
let calcScore pins =

    let rec calcScore pins frame =

        match pins with

        // Strike with determined bonus
        | 10 :: y :: z :: rest -> 10 + y + z + calcScore (y :: z :: rest) (frame + 1)

        // Strike -without- determined bonus
        | 10 :: y :: [] -> 0

        // Spare with determined bonus
        | x :: y :: z :: rest when x + y = 10 -> 10 + z + calcScore (z :: rest) (frame + 1)

        // Spare -without- determined bonus
        | x :: y :: [] when x + y = 10 -> 0

        // Open frame
        | x :: y :: rest -> x + y + calcScore (rest) (frame + 1)

        // Special last frame
        | x :: y :: z :: [] when frame = 10 -> x + y + z

        // Otherwise
        | _ -> 0

    calcScore pins 1

If you are familiar with functional programming and pattern matching, the code above should be pretty obvious. I will not go into much depth explaining it, but suffice it to say that it is a recursive function traversing the list of pins knocked over, aggregating the score as it goes.

The rest of the program, responsible for keeping track of state, was kept in C#. After adding a reference to the F# module, calling into the calculating function is as simple as:

public class Player
{
    private readonly List<int> pinsKnockedOver;
    
    // snip...
    
    public int CalculateScore()
    {
        var pins = ListModule.OfSeq(pinsKnockedOver);
        return BowlingCalculator.CalculateScore(pins);
    }
}

Both being first class .NET citizens, interoperability between C# and F# is a breeze. The only hitch at this point was that my F# function required an F# list as its argument, while the Player class uses a regular List<T> to keep track of the pins knocked over. ListModule.OfSeq() converts any IEnumerable<T> into an F# list, solving that problem with ease.

The complete source code is available on GitHub at https://github.com/tormodfj/katas/tree/master/mixed/Bowling.

In my opinion, this solution takes the best from two worlds, using the imperative C# for state tracking and the functional F# for calculations. Learning the functional paradigm is like acquiring a new tool in your toolbox, enabling you to view problems from other points of view.

Advertisements

Converting an IList<T> to an FSharpList<T>

When calling F# functions from other .NET languages, you may encounter situations where you need to pass parameters of type 'T list. F# lists are immutable linked lists, appearing as the type FSharpList<T> in other .NET languages. Hence, passing a typical IList<T> is not possible. Luckily, converting an IList<T> to an FSharpList<T> is easily accomplished by recursively calling FSharpList<T>.Cons, passing each element of the source list. I keep the following code around for those occasions:

public static class Interop
{
	public static FSharpList<T> ToFSharpList<T>(this IList<T> input)
	{
		return CreateFSharpList(input, 0);
	}

	private static FSharpList<T> CreateFSharpList<T>(IList<T> input, int index)
	{
		if(index >= input.Count)
		{
			return FSharpList<T>.Empty;
		}
		else
		{
			return FSharpList<T>.Cons(input[index], CreateFSharpList(input, index + 1));
		}
	}
}

Note how F# lists are terminated using FSharpList<T>.Empty. Using this piece of code is as simple as:

var list = new List<int> { 1, 2, 3, 4 };
var fsharpList = list.ToFSharpList();

Update: @rickasaurus made me aware of the List.ofSeq<'T> function in the F# core library. This function solves the same issue. And, unlike my solution, its implementation is not prone to stack overflows when the input list grows large. In C#, this function is called like this:

var list = new List<int> { 1, 2, 3, 4 };
var fsharpList = ListModule.OfSeq(list);

Tail Recursion in C# and F#

For those of you who are unfamiliar with the notion of tail recursion, let me quote Wikipedia’s definition.

In computer science, tail recursion (or tail-end recursion) is a special case of recursion in which the last operation of the function, the tail call, is a recursive call

Tail recursion is essential in functional languages like F#, where iterative solutions are often implemented using recursion. If the recursion gets too deep, a stack overflow occurs, and your program crashes brutally. The rationale behind tail recursion is that if the recursive call is the last operation of the function, the stack frame of the current function invocation can be discarded before the recursive function invocation is made.

Rather than spending too much time discussing programming theory, let me present two equivalent programs, both containing tail recursion.

C#

class Program
{
	static int n = 1000000;

	static void Countdown()
	{
		if (0 > n--) return;
		Countdown();
	}

	static void Main(string[] args)
	{
		Countdown();
		Console.WriteLine("Done");
	}
}

F#

let n = 1000000

let rec countdown n =
    match n with
    | 0 -> ()
    | _ -> countdown (n-1)

countdown n
printfn "Done"

These two programs are semantically equivalent. They both use tail recursion to count from 1 000 000 to zero, before writing “Done” to the console.

Let us first look at the F# solution. Apart from being precise and easy to comprehend, it actually works. In fact, the F# compiler is smart enough to optimize the countdown function into a simple while loop, producing MSIL equivalent to the following C# code:

public static void countdown(int n)
{
    while (true)
    {
        switch (n)
        {
            case 0:
                return;
        }
        n--;
    }
}

But what about the tail recursive C# solution? While tail recursion optimization has been proposed to Microsoft, the current C# compiler does nothing of the kind. Hence, the resulting MSIL contains a recursive Countdown method. The question is then: “Will the C# solution result in a stack overflow?” Interestingly, the answer is: “It depends.”

It turns out, if you compile the C# code with “Platform target: Any CPU” and run it on a 64-bit version of the Microsoft .NET runtime, the JIT compiler will actually perform tail recursion optimization from the MSIL itself, resulting in a working program. If, however, you compile with “Platform target: x86” or run the program on a 32-bit version of the Microsoft .NET runtime, a stack overflow occurs. This behavior is described in the blog post “Tail call JIT conditions” by David Broman. Basically, the feature sets of the 64-bit and 32-bit versions of the JIT compiler do not coincide.

So, unless you are 100 % certain that your C# application will run on the 64-bit runtime, do no employ tail recursion with the intent of preventing stack overflows. Then again, if you are writing imperative C# code, tail recursion will probably not cross your mind as the best solution to any of your problems.

Fibonacci Fun with F#

As you probably know, the Fibonacci sequence is the infinite sequence of integers where each element is the sum of the previous two (the first two elements being 0 and 1). Recently, I was inspired by a blog post, Ruby vs. Haskell – project Euler #25 deathmatch. In particular, I enjoyed the Haskell solution for its simplicity and declarativeness.

I decided to try and solve the same problem, but using F#, the functional programming language being introduced as a first class .NET citizen for the first time with Visual Studio 2010. If you have never seen F# code before, the snippets included in this post may be difficult to comprehend, especially if you are used to reading code written in imperative languages like C# or Java.

To declaratively create infinite sequences in F#, the Seq module provides the unfold function. This function takes two parameters, a generator function and an initial state. The generator function must take a state parameter and produce an option tuple with a sequence element and a new state. In F# notation, the unfold function has the signature Seq.unfold : ('State -> 'T * 'State option) -> 'State -> seq<'T>. Note that if the generator function always returns Some(_) and never None, the resulting sequence will be infinite.

An example of Seq.unfold in action is shown in the following one-liner, producing an infinite sequence of all positive integers.

let positiveIntegers = Seq.unfold (fun x -> Some(x, x + 1)) 1

In this example, the generator function takes an integer state as input. The sequence element produced by this function is the current state, while the next state is calculated by incrementing the current state. Thus, each time the generator function is called, the input integer state is one higher than the previous time. The initial state, 1, is passed as the final parameter to Seq.unfold. The result is the sequence “1, 2, 3, …, ∞” (or, strictly speaking, as far as 32 bit integers go).

So, how do we go from this sequence to the Fibonacci sequence? First of all, since each element of the Fibonacci sequence is the sum of the previous two, the state cannot consist only of a single integer. Rather, the state has to be a tuple of two integers. By choosing (0, 1) as the initial state, the generator function can use the first tuple element as sequence output and construct the next state as ([next], [current] + [next]), where [current] and [next] are the first and second element, respectively, from the current state tuple.

Translated into F# code, this yields the following definition of the Fibonacci sequence.

let fibonacci =
    Seq.unfold
        (fun (current, next) -> Some(current, (next, current + next)))
        (0, 1)

When enumerating this sequence, however, one problem becomes apparent. Element number 48 is a negative number. This is definitely erroneous behavior, as the Fibonacci sequence consists solely of positive integers. The error is due to the limited value space of 32 bit integers, causing an overflow. To circumvent this problem, we can use the BigInteger type, capable of representing integers of arbitrary size. The only change we need to make to our original Fibonacci definition is to change the initial state tuple to contain BigInteger values. The F# type inference system handles the rest.

open System.Numerics

let fibonacci =
    Seq.unfold
        (fun (current, next) -> Some(current, (next, current + next)))
        (BigInteger 0, BigInteger 1)

Now to the actual solution to Project Euler #25. Modelled after the previously mentioned Haskell solution, my solution also counts the number of elements in the Fibonacci sequence having a value less than 10999.

Again, translating this into F# results in the following code.

open System.Numerics

let limit = BigInteger.Pow(BigInteger 10, 999)

let fibonacci =
    Seq.unfold
        (fun (current, next) -> Some(current, (next, current + next)))
        (BigInteger 0, BigInteger 1)

let term =
    fibonacci
    |> Seq.takeWhile (fun n -> n < limit)
    |> Seq.length

printfn "%d" term

I am intrigued by how this functional solution focuses on what the Fibonacci sequence is, rather than how it is calculated. Constructing an infinite Fibonacci sequence in C# would typically require an iterator consisting of an infinite loop, representing state with two local variables. Counting elements having a value less than 10999, however, could easily have been accomplished in a functional manner using LINQ.