Category: F#

F# from a C# Developers Perspective – Part 3

I’ve been writing a lot of (production) F# since my last post on this topic and while I don’t consider myself an expert (by any means!) I’ve certainly become a lot more familiar with the language and have found myself falling into what Isaac Abraham refers to as “the pit of success”.

It was hard to understand, or at least appreciate, what he meant by this on my first pass through his book (which I recommend by the way – that really helped get me on my way) and I think that’s because F# doesn’t lead you towards success (i.e. bug free code) through any one language feature – but rather how all its features interlock and go together.

It really came together for me when I undertook a significant refactoring of some code and when I had finished and pressed build and it compiled without errors and warnings I realised that I knew what I’d done worked. I didn’t have to test it or try it. I knew it had to work (and there’s no twist in this tale – it did).

Amongst other things I had no mutable state, I’d used single case case discriminated unions to protect against mis-assignments, I’d used the type system to protect against bad data, I’d used the Seq functions almost exclusively to work on collections, I’d favoured matching over if/then/else constructs and had no missing matches, I’d used modules and namespaces to organise my code, and I had no nulls!

In fact as this application comes together, its a mobile app that I am building with the Fabulous framework – and the Model->View->Update architecture is perfect for a functional language, the only thing I really find myself worrying about is does the UI layout correctly.

It’s been a fascinating, and very positive, experience for someone who has been working with C# and JavaScript for so many years. I’d sum it up as this:

F# makes me work a little harder to express concepts in code but once I have I am more confident the result is correct and far less brittle and as a result I am more productive.

It’s not that C# “forces” you to write brittle code – but it makes it far easier to and so in some ways, putting the paradigms to one side and focusing on the un-brittleness of code (and as someone who has used all three languages), I am starting to think of F# being to C# as C# is to C++.

Posted in F#

F# from a C# Developers Perspective – Part 2

My customary warning on these posts: I am absolutely not a F# expert – these posts are about things that caught me out or surprised me as I begin to learn F# as an experienced C# developer. You can find part 1 here.

This is something that’s caught me out a lot while picking up F#. A typical function in F# might look like this:

let multiply valueOne =
	let userInput = int(System.Console.ReadLine())
	valueOne * userInput

Now how about a parameterless function, is it this:

let multiply =
	let valueOne = int(System.Console.ReadLine())
	let valueTwo = int(System.Console.ReadLine())
	valueOne * valueTwo

In short: no. This is not a function – the code will execute once and the result be assigned to the immutable constant multiply. To make this a function you need to add parentheses:

let multiply () =
	let valueOne = int(System.Console.ReadLine())
	let valueTwo = int(System.Console.ReadLine())
	valueOne * valueTwo

As both are perfectly valid syntax the compiler will process them without warning, it has no way of divining your intent. In this case you’ll probably notice the issue because of the need for user input but I had a really puzzling situation with the setting of the consoles foreground colour which never seemed to quite do what I expected. Needless to say – I’d made this mistake!

Posted in F#

F# from a C# Developers Perspective – Part 1

Note: for those waiting for me to post more videos about Function Monkey they are on the way, I’m on a working / cycling holiday in Mallorca and don’t really have the setup to record decent audio.

While I’m still a complete beginner with F# and very much in the heavy learning phase I thought it might be interesting to write about some of the things I’ve learned along the way.

I can’t stress enough that I’m a beginner with this stuff – so hopefully while its interesting please don’t treat the examples shown as great usage of F#, rather observations made on my way to gaining a better understanding.

A good place to start might be with writing the F# equivalent of this simple and fairly typical C# construct:

internal class Program
{
    private static int ProcessInput(string input, int state)
    {
        int newState = state;
        switch (input)
        {
            case "A": newState = state + 1;
                break;
            case "M": newState = state * 2;
                break;
        }

        Console.WriteLine(newState);
        return newState;
    }
    
    public static void Main(string[] args)
    {
        bool shouldQuit = false;
        int state = 0;
        
        while (!shouldQuit)
        {
            string input = Console.ReadLine().ToUpper();
            shouldQuit = input == "Q";
            if (!shouldQuit)
            {
                state = ProcessInput(input, state);
            }
        }
    }
}

Essentially keep looping and processing user input until the user signals they’re done. My first attempt at this looked very much like the C# equivalent:

open System

[<EntryPoint>]
let main argv =
    let processInputs value input =
        let newValue = match input with
            | "A" -> value + 1
            | "M" -> value * 2
            | _ -> value
        printf "%d\n" newValue
        newValue
        
    let mutable shouldQuit = false
    let mutable state = 0
    while not shouldQuit do
        let input = System.Console.ReadLine().ToUpper()
        shouldQuit <- input = "Q"
        state <- match shouldQuit with
            | true -> state
            | false -> processInputs state input
            
    0 // return an integer exit code

As you might know, in F# data is immutable by default and use of the mutable keyword is a smell – it may sometimes be necessary but its a good sign you’re going about something in a none F# way.

One way to solve this would be to replace the while loop with a recursive function however in this case the recursion is essentially unbounded as it depends on user input. To a C# mindset that is something likely to blow the stack with a good old StackOverflowException. Here’s an example of a recursive approach written in C# and the stack trace that results in the debugger after a few key presses:

class Program
{
    private static int ProcessInput(string input, int state)
    {
        int newState = state;
        switch (input)
        {
            case "A": newState = state + 1;
                break;
            case "M": newState = state * 2;
                break;
        }

        Console.WriteLine(newState);
        return newState;
    }

    private static int RecursiveLoop(int state)
    {
        string input = Console.ReadLine()?.ToUpper();
        if (input == "Q")
        {
            return state;
        }

        return RecursiveLoop(ProcessInput(input, state));
    }
    
    static int Main(string[] args)
    {
        return RecursiveLoop(0);
    }
}

Here’s the same code written in F#, with the mutable keyword eradicated, and the stack trace after a few key presses:

open System

[<EntryPoint>]
let main _ =
    let processInput value input =
        let newValue = match input with
            | "A" -> value + 1
            | "M" -> value * 2
            | _ -> value
        printf "%d\n" newValue
        newValue
        
    let rec inputTailLoop state =
        let input = System.Console.ReadLine().ToUpper()
        match input with
            | "Q" -> state
            | _ -> inputTailLoop (processInput state input)
            
    let startingState = 0
    let finishingState = inputTailLoop startingState
    finishingState

The stack has not grown! So what’s going on?

The recursive functions, in both C# and F#, are examples of something called tail recursion. Tail recursion occurs when the very last operation a function performs is to call itself and when this occurs their is no need to preserve any data on the stack.

The F# compiler, unlike the C# compiler, recognises this and essentially is able to treat the recursive method as an iteration and avoid the stack growth and by doing so it enables us to solve a whole new class of problems without requiring mutable data.

Having posted about this on Twitter this prompted some discussion amongst the F# wizards about how tail recursion is also generally considered an anti-pattern and Isaac Abraham came through with an example as to how this could be solved using F# sequences as shown below (my butchered version of his original!):

open System

[<EntryPoint>]
let main _ =
    let processInput value input =
        let newValue = match input with
            | "A" -> value + 1
            | "M" -> value * 2
            | _ -> value
        printf "%d\n" newValue
        newValue
    
    let inputs = seq {
        while true do
            yield System.Console.ReadLine()
    }
    let startingState = 0
    let finishingState =
        inputs
        |> Seq.map (fun input -> input.ToUpper())
        |> Seq.takeWhile (fun input -> not(input = "Q"))
        |> Seq.fold processInput startingState
    
    finishingState

Essentially what we’ve done here is be explicit about the iteration that was implicit in the tail recursion. I’d used the Seq namespace quite heavily but I’m not sure I’d have made the leap to using the seq { } construct to solve this problem without Isaac’s help (thank you!).

For anyone interested I’m writing a simple version of the classic Star Trek game to teach myself F#. The code is, I’m sure, woeful and it gets refactored massively almost daily at the moment – but you’re welcome to take a look, it’s on GitHub.

Finally I’d like to stress again – I’m an absolute beginner at F# so please, please, don’t use the code above as exemplars but rather curios!

Posted in F#

Contact

  • If you're looking for help with C#, .NET, Azure, Architecture, or would simply value an independent opinion then please get in touch here or over on Twitter.

Recent Posts

Recent Tweets

Recent Comments

Archives

Categories

Meta

GiottoPress by Enrique Chavez