Showing posts with label Immutable. Show all posts
Showing posts with label Immutable. Show all posts

Saturday, September 29, 2018

Immutability in .NET

First off, what are immutable objects

Immutable is pretty much a fancy word for unchangeable. In other words, once you create an object it will have the same properties for its entire life. No way to reassign for example a name, if you want to do that you would have to create a new object with the same properties but with the new name. Immutable = Not Mutable

Why bother?

I didn't understand the point of immutable objects, I though that as long as we encapsulate and follow good object oriented guidelines then we are good to go.. Right?
Let's look at a naive example of things that can go wrong:
public class CSharpPoco
{
    private uint _value;
    public uint Value => _value;
    public void Increment()
    {
        _value++;
    }
    public uint GetNext()
    {
        Increment();
        return _value;
    }
}
        
public class ServiceLayer
{
    private CSharpPoco _poco = new CSharpPoco();
    public CSharpPoco GetPoco()
    {
        return _poco;
    }
    public uint PreviewNextValue()
    {
        return _poco.GetNext();
    }
}

In the service layer we have 2 methods to call, get the poco and preview its next value.
The following service code would throw the side effect exception:

var service = new ServiceLayer();
var poco = service.GetPoco();
var firstValue = poco.Value;
var preview = service.GetPreviewValue();
if (preview <= firstValue)
    throw new Exception("preview can't be smaller then or equal to the previus value");
if (poco.Value == preview)
    throw new Exception("side effect");

Meaning, we get an unexpected side-effect by calling the second method in the service. It manages to change the value of the first service calls result. It was zero, but after the preview call it has been set to 1. This is quite a simple example, but after having debugged scenarios like these in production code with huge code bases.. You get the idea, a unexpected side effect is often a cause for hard-to-find bugs.
So, how could immutability have helped us here? once the var poco = service.GetPoco() was called, the result would never change. Preferably we would not be able to reasign the variable poco to other references either (similar to the const keyword in TypeScript or F# let). So instead of var I would have liked a const poco = service.

What options do we have in .NET?

Readonly objects in C# with constructor lists

public class CSharpImmutableConstructorList
{
    public readonly Guid Id;
    public readonly string Name;
    public readonly string DisplayName;
    public CSharpImmutableConstructorList(Guid id, string name, string displayName)
    {
        Id = id;
        Name = name;
        DisplayName = displayName;
    }

    public CSharpImmutableConstructorList SetDisplayName(string displayName)
    {
        return new CSharpImmutableConstructorList(Id, Name, displayName);
    }
}
Basically the magic here is done by the readonly keyword that states that only the constructor can set the value of the variable. Once it has been set, it can only be read. For larger objects, it can get a little heavy on the constructor and you have to supply all the values every time you want to change. For example the SetDisplayName function, it supplies the Id and Name even though they have the same value as before.
If we add more properties to this class, we would have to change all calls to the constructor and add the new properties for them as well. So a little heavy on the maintenance side.

Readonly objets in C# with Modify pattern

public class CSharpImmutableModifyPattern
{
    public readonly Guid Id;
    public readonly string Name;
    public readonly string DisplayName;
    public static CSharpImmutableModifyPattern Default { get; } = new CSharpImmutableModifyPattern(Guid.Empty, string.Empty, string.Empty);
    private CSharpImmutableModifyPattern(Guid id, string name, string displayName)
    {
        Id = id;
        Name = name;
        DisplayName = displayName;
    }
    public CSharpImmutableModifyPattern Modify(Guid? id = null, string name = null, string displayName = null)
    {
        return new CSharpImmutableModifyPattern
            (
                id ?? Id,
                name ?? Name,
                displayName ?? DisplayName
            );
    }
    public CSharpImmutableModifyPattern SetDisplayName(string displayName)
    {
        return Modify(displayName: displayName);
    }
}
This is pretty much the same pattern as I've described in a previous post (Functional adventures in .NET C# - Part 1, immutable objects), the difference is that we use the readonly members instead of get-only fields.
Also note that the constructor is set to private to prevent usage of it from outside, instead we will use the Default static get-only field that sets up a default invariant of the class and call the new method Modify on it.
The nice thing with the Modify pattern is that you don't have to supply anything else then the changed property as shown in the SetDisplayName method. Even if we add new parameters, we don't have to change the SetDisplayName method as it specifies that it only wants to supply the displayName and nothing else.

Record types in F#

module Techdump =
    open System
    type FSharpRecord =
        {
            Id : Guid
            Name : string
            DisplayName : string
        }
        member this.SetDisplayName displayName =
            { this with DisplayName = displayName }

The F# Record version of the same type as show before. Used from C# this type feels similar to the C# Constructor List version as you have to supply all the constructor parameters when calling new. The magic happens in the SetDisplayName function that takes a new displayName value and then calls the record constructor with the current record and whatever fields have changed. I.e. the with keyword in record construction. We get the power of CSharpImmutableModifyPattern, but without having to maintain a Modify method, it is all included in the language.


Performance

In this part we will look at the run-time performance the different immutable patterns described above. 

Performance test source code


CSharpPoco
public class CSharpPoco
{
    public Guid Id { get; private set; }
    public string Name { get; private set; }
    public string DisplayName { get; private set; }
    public CSharpPoco(Guid id, string name, string displayName)
    {
        Id = id;
        Name = name;
        DisplayName = displayName;
    }

    public void SetDisplayName(string displayName)
    {
        DisplayName = displayName;
    }
}
Added a C# poco object so that we have a baseline to run against. I.e, here we just mutate the object. No new instance is created, this is the traditional way of changing a value in an object.

Performance tester
public class ImmutabilityPerformance
{
 public void Execute()
 {
  Log("--------------------------------------");
  Log("... ImmutabilityPerformance");
  ExecuteTest(1_000_000);
 }
 
 
 private void ExecuteTest(int iterations)
 {
  string s = string.Empty;
  try
  {
   var data = new List<string> { "Melissa Lewis", "Maya", "Smith", "Beverly Marsh", "Jane Vasko", "Molly Bloom" };
   var csharpPocoTimings = new RunningAverage();
   var fsharpRecordTimings = new RunningAverage();
   var csharpConstructorTimings = new RunningAverage();
   var csharpModifyTimings = new RunningAverage();
   for (int i = 0; i < iterations; i++)
   {
    var csharpPoco = new CSharpPoco(Guid.NewGuid(), "Jessica Chastain", "Jessica Chastain");
    var fsharpRecordOriginal = new Techdump.FSharpRecord(Guid.NewGuid(), "Jessica Chastain", "Jessica Chastain");
    var csharpConstructorOriginal = new CSharpImmutableConstructorList(Guid.NewGuid(), "Jessica Chastain", "Jessica Chastain");
    var csharpModifyOriginal = CSharpImmutableModifyPattern.Default.Modify(Guid.NewGuid(), "Jessica Chastain", "Jessica Chastain");

    for (int dataIndex = 0; dataIndex < data.Count; dataIndex++)
    {
     var item = data[dataIndex];


     csharpPocoTimings.Add(TimeAction(() =>
     {
      csharpPoco.SetDisplayName(item);
     }));
     if (csharpPoco != null)
      s = csharpPoco.DisplayName;

     Techdump.FSharpRecord fsharpRecordModified = null;
     fsharpRecordTimings.Add(TimeAction(() =>
     {
      fsharpRecordModified = fsharpRecordOriginal.SetDisplayName(item);
     }));
     if (fsharpRecordModified != null)
      s = fsharpRecordModified.DisplayName;

     CSharpImmutableConstructorList csharpConstructorModified = null;
     csharpConstructorTimings.Add(TimeAction(() =>
     {
      csharpConstructorModified = csharpConstructorOriginal.SetDisplayName(item);
     }));
     if (fsharpRecordModified != null)
      s = csharpConstructorModified.DisplayName;

     CSharpImmutableModifyPattern csharpModifyModified = null;
     csharpModifyTimings.Add(TimeAction(() =>
     {
      csharpModifyModified = csharpModifyOriginal.SetDisplayName(item);
     }));
     if (csharpModifyModified != null)
      s = csharpModifyModified.DisplayName;
    }
   }
   Log($"CSharpPoco\tIterations:\t{iterations}\tAverage:\t{csharpPocoTimings.Average:0.000}\tticks\tTotal:\t{csharpPocoTimings.Total:0.000}\tticks");
   Log($"FSharpRecord\tIterations:\t{iterations}\tAverage:\t{fsharpRecordTimings.Average:0.000}\tticks\tTotal:\t{fsharpRecordTimings.Total:0.000}\tticks");
   Log($"CSharpImmutableConstructorList\tIterations:\t{iterations}\tAverage:\t{csharpConstructorTimings.Average:0.000}\tticks\tTotal:\t{csharpConstructorTimings.Total:0.000}\tticks");
   Log($"CSharpImmutableModifyPattern\tIterations:\t{iterations}\tAverage:\t{csharpModifyTimings.Average:0.000}\tticks\tTotal:\t{csharpModifyTimings.Total:0.000}\tticks");
  }
  catch (Exception ex)
  {
   Log($"Fail\tDataCount\t2\tIterations:\t{iterations}\tFailed\t{ex.Message}");
  }
 }


 private float TimeAction(Action action)
 {
  var sw = Stopwatch.StartNew();
  action();
  sw.Stop();
  return sw.ElapsedTicks;
 }

 private void Log(string s)
 {
  Console.WriteLine(s);
  File.AppendAllText(@"c:\temp\enumToStringTest.txt", $"{s}{Environment.NewLine}");
 }
 
}

And the RunningAverage class from a previous post.

Results

ImmutabilityPerformance
Iterations
Average (ticks)
Total (ticks)
CSharpPoco 1000000 0.090 537402
FSharpRecord 1000000 0.121727156
CSharpImmutableConstructorList 1000000 0.120 720220
CSharpImmutableModifyPattern 1000000 0.161 965545

Here we can see that the poco baseline test is the fastest by far. Using the F# Record type and C# locked down object with constructor are pretty much equal in execution. The modify pattern in the C# code really drops the performance but gives more readable code, at least if we have long constructor lists in objects.

Rewritten increment example

Let's go back and look at the first increment example again and try to rewrite it with immutability
public class CSharpImmutable
{
    public readonly uint Value;
    public CSharpImmutable(uint value)
    {
        Value = value;
    }
    public CSharpImmutable Increment()
    {
        return new CSharpImmutable(Value + 1);
    }
    public uint GetNext()
    {
        return Value + 1;
    }
}

And in F#
type FsharpIncrement =
    {
        Value : uint32    
    }
    member this.Increment () =
        { this with Value = this.Value + 1u }
    member this.GetNext () =
        this.Value + 1u

Conclusions

In my opinion Immutable objects are the way to go if you want to write maintainable code for the long run, what technique you choose is entirely up to you. There are probably other ways to achieve the same that I don't know about, if you have ideas please post a comment!

After I started writing F# code, and started getting all the immutability features for free and especially the with keyword for records has persuaded me to start writing all my core business models in F#.
let point' = { point with X = 2; }
In my eyes, that line of code just there, is so damn beautiful.



All code provided as-is. This is copied from my own code-base, May need some additional programming to work. Use for whatever you want, how you want! If you find this helpful, please leave a comment or share a link, not required but appreciated! :)

Wednesday, May 9, 2018

Functional Adventures in F# - Persisting Application State



In this part we will look at how to persist the application state to disk. It should not be too hard to modify for usage with other persistence solutions.

This post is part of a series:
Functional Adventures in F# - A simple planner
Functional Adventures in F# - Calling F# from C#
Functional Adventures in F# - Using Map Collections
Functional Adventures in F# - Application State
Functional Adventures in F# - Types with member functions
Functional Adventures in F# - Getting rid of loops
Functional Adventures in F# - Getting rid of temp variables
Functional Adventures in F# - The MailboxProcessor
Functional Adventures in F# - Persisting Application State
Functional Adventures in F# - Adding Snapshot Persisting
Functional Adventures in F# - Type-safe identifiers
Functional Adventures in F# - Event sourcing lessons learned

Storing all actions

The idea is pretty simple, we will store all actions sent to the AppHolder MailboxProcessor and whenever we want to re-initiate the application state, we just load all the actions from storage and run them through the processor again and we should end up with the same application state.

This has been described by other people, for example Martin Fowler, if you have the time then head over there and read his article about event sourcing.

For this we will create a module called AppPersister. It will handle the actual storing and retrieving of the events from disk. So it will have side-effects and thus not be purely functional.... So lets just throw all those concepts out the door. But, this is a great opportunity to show some nice features of F# that will help write this kind of code a little more ... functional?
For serialization I chose to use the json format, and serializer is the JSON.NET library by Newtonsoft that can be added to your project with NuGet.

Some code for starters:
module AppPersister =
    open System
    open System.Reflection
    open System.IO
    open Newtonsoft.Json
    
    let private store = @".\store\"
Basically we just create a new module that will handle the persisting of actions... Here we also define that the store should be a subdirectory for the application.
    let private createActionFilename (action:obj) =
        let now = DateTime.UtcNow
        let hourPath = now.ToString("yyyy-MM-dd HH")
        let fullPath = Path.Combine(store, hourPath)
        let di = new DirectoryInfo(fullPath)
        di.Create()
        let t = action.GetType()
        let filename = now.ToString("yyyy-MM-dd hh_mm_ss_fffffff+") + now.Ticks.ToString() + "." + t.Name + ".action"
        let fullFilename = Path.Combine(fullPath, filename)
        fullFilename
The createActionFilename function does just that, it generates a new unique filename for the action by combining todays date and time, throwing in the total number of ticks to ensure that we always have a fresh value and lastly adding the type of action and the extension '.action'. Here we also create the directory if it does not exist already for the current date and hour (UTC), the DirectoryInfo.Create method is safe to run on an already existing directory so we do no other checking ourselves.
    let PersistAction (action:obj) =
        let fullFilename = createActionFilename action
        let json = JsonConvert.SerializeObject(action)
        File.WriteAllText(fullFilename,  json)
        ()
The PersisAction function handles the actual writing of the action to disk. We call createActionFilename to get the full filename and then use JsonConvert to serialize the action to a json string. Lastly we write the file with the nice File.WriteAllText method.

Now that we can write the actions, lets write some code to read them from disk.
    let GetAllActions () =
        let di = new DirectoryInfo(store)
        let actions =
            di.GetFiles("*.action", SearchOption.AllDirectories)
            |> Seq.map (fun (fi:FileInfo) -> File.ReadAllText(fi.FullName), fi.Name)
            |> Seq.map (fun x -> (getAction x))
            |> Seq.toArray
        actions

  • Here we use the DirectoryInfo.GetFiles built in method to find all files with the .action extension in any subdirectory in the store path. The result is an array of FileInfo objects that we pipe to a 
  • Seq.map where we return a Tuple containing the file contents and filename and pipe that tuple into
  • another Seq.map where we call getAction for all elements. This function will be tasked with deserializing the json to the correct type
  • Lastly we pipe the contents to Seq.toArray to make the result concrete. To my understanding is that the Seq constructs work a little like the IEnumerable and do lazy evaluation if you do not actually list it. 
    let private getAction (json:string, filename:string) =
        let split = filename.Split('.')
        let actionName = split.[1]
        let actionNameWithNamespace = "dreamstatecoding.core.Actions+" + actionName
        let t = Assembly.GetExecutingAssembly().GetType(actionNameWithNamespace)
        JsonConvert.DeserializeObject(json, t)
Lastly, the getAction function that is called from GetAllActions. Here we split the filename and pick out the part containing the name of the Action and then as the currently executing assembly to find the Type for that. Notice that we need to prefix the action name with the namespace name to make it work. In my solution I have all my actions in 1 module, so this works.


Rewriting AppHolder to work with persisted actions

Next step is to rewrite the AppHolder module from previous part to work with the AppPersister module.

So what we want to do here is to separate actual real time Actions from Replay actions from the persisting, mainly so that they do not get persisted again (duplicated).

So, lets put up a new discriminated union that defines what we want to do
    type Message =
        | Replay of obj
        | Action of obj

So, either we want to execute a Replay object or execute an Action object.
    let private Processor = Agent.Start(fun inbox ->
        let rec loop (s : AppliationState) =
            async {
                let! message = inbox.Receive()
                let (action:obj) = 
                    match message with
                    | Action a -> 
                        AppPersister.PersistAction a
                        a
                    | Replay a -> a

                let s' = s.HandleAction action
                state <- s'
                counter <- counter + 1
                return! loop s'
                }
        loop AppliationState.Default)
Now we rewrite our MailboxProcessor (Agent) to take a message instead of object directly. The first step is to pattern-match the received message to the type and get out the payload object.
If we are handling an Action we want to persist it as well, so lets put that function call here as well. Otherwise no change here.
    let HandleAction (action:obj) =
        Processor.Post (Action action)
The old HandleAction code called Processor.Post with the action directly. Now we must state that it is an Action, and not a Replay.
    let private HandleReplayAction (action:obj) =
        Processor.Post (Replay action)
The same goes for the Replay execution, we just add a new function that executes actions as Replays
    let InitiateFromStore () =
        AppPersister.GetAllActions()
        |> Array.map (fun x -> (HandleReplayAction x))
        |> ignore
        ()

Lastly, a function to initialize the store, we pipe all the actions loaded from persistence to the HandleReplayAction and then pipe the results from that to ignore. This means that we are not really interested in the results from this function call, in the end we just return unit from the InitiateFromStore function.
I put the call to this into my Program.cs file, it will load all the actions already executed from the store and execute them all as Replay actions.

Conclusions

In this part we have looked at how to persist the application state as a series of actions and then re-creating the application state when the application is restarted.
For applications handling lots and lots of actions, we may want to limit the number of actions needed to recreate the up to date state.. So in the next part we will look at snapshots. My plan is to upload the code to git after the snapshot part has been added.

All code provided as-is. This is copied from my own code-base, May need some additional programming to work. Use for whatever you want, how you want! If you find this helpful, please leave a comment, not required but appreciated! :)

Hope this helps someone out there!

Saturday, April 28, 2018

Functional Adventures in F# - The MailboxProcessor


In this post we will look at MailboxProcessor in F#.

This post is part of a series:
Functional Adventures in F# - A simple planner
Functional Adventures in F# - Calling F# from C#
Functional Adventures in F# - Using Map Collections
Functional Adventures in F# - Application State
Functional Adventures in F# - Types with member functions
Functional Adventures in F# - Getting rid of loops
Functional Adventures in F# - Getting rid of temp variables
Functional Adventures in F# - The MailboxProcessor
Functional Adventures in F# - Persisting Application State
Functional Adventures in F# - Adding Snapshot Persisting
Functional Adventures in F# - Type-safe identifiers
Functional Adventures in F# - Event sourcing lessons learned

MailboxProcessor

This continues with the code from Application State post.
Mainly the GameState type
and GameState =
 {
  PlayerStore:PlayerStore
  UnitStore:UnitStore
 }
 member this.HandleAction (action:obj) (state:GameState) =
  {
   PlayerStore = state.PlayerStore.HandleAction action state.UserStore
   UnitStore = state.UnitStore.HandleAction action state.AmmunitionStore 
  }


My goal is to incorporate F# with C# in a nice way. And as described in the Application State post, the core application model and all actions that can be made in the application will be modeled in F#. But to prevent a multithreaded C# application to corrupt the state we need to serialize the commands that are processed.
In C# I would have used a background Thread and a Queue<T> and written a locks to synchronize the reads and writes. Luckily in F#, we have all that nicely packaged in the built in MailboxProcessor.

The first line redefines the MailboxProcessor to the term Agent instead, this seems to be something that a lot of people are doing, so lets stick to that for the time being.
After that we define a F# static class, i.e. an abstract and sealed class with only static members. (this is what C# does under the hood).

type Agent<'T> = MailboxProcessor<'T>     
[<AbstractClass; Sealed>]
type GameHolder private () =
 static let mutable state : GameState = 
  {
   PlayerStore = { Players = Map.empty }
   UnitStore = { Units = Map.empty }
  }
 static member State : GameState = state
 static member private Processor = Agent.Start(fun inbox ->
  let rec loop =
   async {
    let! action = inbox.Receive()
    state <- state.HandleAction action state
    return! loop
    }
  loop)
 static member HandleAction (action:obj) =
  GameHolder.Processor.Post action

In addition we will be allowing for mutation here, something that the business logic in the F# module should be unaware of, but here, we are exposing the current state to the rest of the application so that it is easily accessible.
I.e. C# we can call GameHolder.State and always get the latest state. It is exposed as immutable so there is no risk that other threads will write to it.

After that we define the MailboxProcessor<'T> or in this case the redefined Agent<'T> as a private static member of the class.
What happens in the recursive part is a little iffy for me still. To my understanding the let! (with the exclamation mark) makes the inbox.Receive (that is also an async call) an synchronous call and stores its result in the action value.
If anyone has detailed explanation of what is going on here, please feel free to comment as I was unable to find details of this seems just to be the way things are done.

The HandleAction method calls the Post method on the MailboxProcessor and thus posts the action to the MailboxProcessor that in turn calls the HandleAction method of the State and mutates the exposed State value.

Update 2018-05-02, forcing serial access

Turns out the MailboxProcessor above does not work the way I thought... In my mind it serialized the processing but it did not. I.e. when multiple actions were sent to it in parallel, it corrupted the state variable.
After looking at this for some time now, I finally had to post the question on stackoverflow.
https://stackoverflow.com/questions/50135825/f-mailboxprocessor-limit-parallelism

Turns out the bad wolf in the drama was the static member. Changing the code to a module instead got the solution to work as expected.

The end result is:
module GameHolder =
    type Agent<'T> = MailboxProcessor<'T>     

    let mutable private state = AppliationState.Default
    let mutable private counter : int = 0
    let GetCurrentState() =  state
    let GetProcessedActionsCounter() = counter
    let private Processor = Agent.Start(fun inbox ->
        let rec loop (s : AppliationState) =
            async {
                let! action = inbox.Receive()
                let s' = s.HandleAction action
                state <- s'
                counter <- counter + 1
                return! loop s'
                }
        loop AppliationState.Default)

    let HandleAction (action:obj) =
        Processor.Post action

I can still get the current application state by calling a 'static' method from C#, in this case GameHolder.GetCurrentState().
So a small change thanks to stackoverflow and we still have a small but neat interface between our C# game/application and it model/business logic that is written in F#.

Finally

In the end. We have a GameHolder class that exposes State and HandleAction to the outside world. Whoever can query the state at anytime, but they are not allowed to change it other then through the HandleAction method.

All code provided as-is. This is copied from my own code-base, May need some additional programming to work. Use for whatever you want, how you want! If you find this helpful, please leave a comment or share a link, not required but appreciated! :)

Hope this helps someone out there!

Friday, March 16, 2018

Functional Adventures in F# - Types with member functions

Lets look at how to structure functions into the types that they are linked to, this helps with keeping the code base clean.

This post is part of a series:
Functional Adventures in F# - A simple planner
Functional Adventures in F# - Calling F# from C#
Functional Adventures in F# - Using Map Collections
Functional Adventures in F# - Application State
Functional Adventures in F# - Types with member functions
Functional Adventures in F# - Getting rid of loops
Functional Adventures in F# - Getting rid of temp variables
Functional Adventures in F# - The MailboxProcessor
Functional Adventures in F# - Persisting Application State
Functional Adventures in F# - Adding Snapshot Persisting
Functional Adventures in F# - Type-safe identifiers
Functional Adventures in F# - Event sourcing lessons learned


I started converting my small but handy 3D math library to F# and very quickly I ran into a problem. Not that unexpected as I am a beginner with F#.
So say that you have some types:
type Vector3 = 
 { 
  X:float
  Y:float
  Z:float 
 }
type Vector4 = 
 { 
  X:float
  Y:float
  Z:float 
  W:float 
 }
That in the end will have quite similar functionality like .. for example Add, Divide etc. With the knowledge that I have so far of F# I ended up with
let addVector3 (value1:Vector3) (value2:Vector3) = 
 {
  X = value1.X + value2.X
  Y = value1.Y + value2.Y
  Z = value1.Z + value2.Z
 }
let addVector4 (value1:Vector4) (value2:Vector4) = 
 {
  X = value1.X + value2.X
  Y = value1.Y + value2.Y
  Z = value1.Z + value2.Z
  W = value1.W + value2.W
 }
I quickly thought that there must be a cleaner way to write this. I like tidy code, neat code.. not code that just looks bad and will turn into a maintenance hell even before it is shipped.
Luckily it turns out you can define functions as members of types. So the above 2 functions would look like:
type Vector3 = 
 { 
  X:float
  Y:float
  Z:float 
 }
 member this.add (value2:Vector3) = 
 {
  X = this.X + value2.X
  Y = this.Y + value2.Y
  Z = this.Z + value2.Z
 }
type Vector4 = 
 { 
  X:float
  Y:float
  Z:float 
  W:float 
 }
 member this.add (value2:Vector4) = 
 {
  X = this.X + value2.X
  Y = this.Y + value2.Y
  Z = this.Z + value2.Z
  W = this.W + value2.W
 }
Here, both are called just add, and they can be invoked directly on the objects.
let value1 = { X = 1.0; Y = 1.0; Z = 1.0 }
let value2 = { X = 2.0; Y = 2.0; Z = 2.0 }
let added = value1.add value2
A little cumbersome syntax if you want to do more complex calculations. So lets look at operator overloading in F# to so that we can get nice arithmetic operators into play for our new types
type Vector3 = 
 { 
  X:float
  Y:float
  Z:float 
 }
 static member (+) (value1:Vector3, value2:Vector3) = 
  {
   X = value1.X + value2.X
   Y = value1.Y + value2.Y
   Z = value1.Z + value2.Z
  }
 static member maxValue = { X = Microsoft.FSharp.Core.float.MaxValue; Y = Microsoft.FSharp.Core.float.MaxValue; Z = Microsoft.FSharp.Core.float.MaxValue; } 

 member this.add (value2:Vector3) = this + value2
This lets us write something like this instead:
let added = value1 + value2
Also note the static member maxValue that is a static function that is invoked by Vector3.maxValue, in this case it just returns the max vector but it can be any function.

So there.

Update: evidently static members should start with capital letter according to design guide-lines. Makes sense as they are easier to spot.

All code provided as-is. This is copied from my own code-base, May need some additional programming to work. Use for whatever you want, how you want! If you find this helpful, please leave a comment, not required but appreciated! :)

Hope this helps someone out there!

Thursday, March 15, 2018

Functional Adventures in F# - Application State


In this article we will go through how to handle complex application state in F#. This will in practice be a rewrite of 'Functional Adventures in C# - Application State'. So I will probably skip a lot of the details and focus on the F# implementation.

This post is part of a series:
Functional Adventures in F# - A simple planner
Functional Adventures in F# - Calling F# from C#
Functional Adventures in F# - Using Map Collections
Functional Adventures in F# - Application State
Functional Adventures in F# - Types with member functions
Functional Adventures in F# - Getting rid of loops
Functional Adventures in F# - Getting rid of temp variables
Functional Adventures in F# - The MailboxProcessor
Functional Adventures in F# - Persisting Application State
Functional Adventures in F# - Adding Snapshot Persisting
Functional Adventures in F# - Type-safe identifiers
Functional Adventures in F# - Event sourcing lessons learned

Overview

Illustration of Application State, different Stores and their model objects. For a lot of illustrations go read the C# article!
Lets be real, nobody read the C# version first. So I'll paste the overview here.
At any given point in time, the whole application state is stored in a class named Application State, it consists of different Stores and they in turn consist of the object model for each store. I.e. Fleet Store might contain Fleets that consists of Ships. All updates to the model are routed to the store in the form of Actions. The application state is immutable, meaning that any object that you get a reference to will never mutate into something else (see previous post in this series on Immutable objects)
So. from the text above we need to define Actions, Application State, and Stores and we should be set to go.

Actions

Actions will be implemented as basic record types. There is no need for anything else fancy. An action should contain all information that is needed to create a new application state.
      newApplicationState = currentApplicationState + action
The code for this part looks like the following
module Actions =
    type InsertCashToPlayerAccount = { Player:GameModel.PlayerId; Amount:GameModel.Cash }
    type Tick = { Time:float; Delta:float }
We defined 2 actions. One that puts money into the players account and the other lets us update each store before rendering a new frame in a game.

Application State

Next up, we will look at the Application State definition, or in this example the GameState definition
module GameState =
    type GameState =
        {
            PlayerStore:PlayerStore
            UnitStore:UnitStore
        }
Here we just define that GameState is a record type that contains 2 stores, the PlayerStore and the UnitStore. Here we will also be adding a way to handle actions, so lets continue with the GameState definition
        
        static member handleAction (state:GameState) (action:obj) =
            {
                PlayerStore = PlayerStore.handleAction state.PlayerStore action
                UnitStore = UnitStore.handleAction state.UnitStore action
            }
Here we add a static member function to the handleAction type (that can be called as: 'GameState.handleAction state action'). We have defined the types here, the state is a GameState and the action is typed to obj, meaning that we can send in any type into this function and it will work. I.e. when we define new actions, we don't need to change anything here. Only if we add a new Store, then we need to add it here obviously.
Also, worth noting is that the action is in turn sent to all Store handlers together with the part of the state that is handled by that Store. Meaning that we can define an action, that is handled by multiple stores. For example the Tick action above.
So basically the handleAction function just builds a new Application State by calling each store and telling them to handle their parts.

Stores

OK, so whats so special about the stores? Nothing really, the Application State is practically a store in itself,
module PlayerStore =
    type PlayerStore =
        {
            Players: Map<PlayerId, Player>
            CurrentTime: float
        }
        static member handleInsertCashToPlayerAccount (state:PlayerStore) (action:InsertCashToPlayerAccount) =
            let player = state.Players.[action.Player]
            let newPlayer = { player with Cash = player.Cash + action.Amount }
            { state with Players = state.Players.Add(player.Id, newPlayer) }            
        static member handleTick (state:PlayerStore) (action:Tick) =
            { state with CurrentTime = action.Time }
        static member handleAction (state:PlayerStore) (action:obj) =
            match action with
            | :? InsertCashToPlayerAccount as a -> PlayerStore.handleInsertCashToPlayerAccount state a
            | :? Tick as a -> PlayerStore.handleTick state a
            | _ -> state

PlayerStore is a record type, just as the GameState type, with a static member handleAction function that has a little different implementation. The key here is the pattern matching on the action, we use the type of the action to determine what handler function should be called to perform whatever it is that the action needs done. As a last state, we have the wild card pattern '_' that returns the old state as it was sent in. I.e. if this actionHandler can't handle the action, nothing is done.
Also notable in the handleInsertCashToPlayerAccount function, the new state is built by taking the current state and applying the action. In this example, finding the player object and constructing a new player object with the added cash in it.

Lastly, lets look at the UnitStore so that we have all the code for our example
module UnitStore =
    type UnitStore =
        {
            Units: Map<GameObjectId, Unit>
            CurrentGameObjectId: GameObjectId
            CurrentTime: float
        }
        static member handleTick (state:UnitStore) (action:Tick) =
            { state with CurrentTime = action.Time }
        static member handleAction (state:UnitStore) (action:obj) =
            match action with
            | :? Tick as a -> UnitStore.handleTick state a
            | _ -> state
Same thing here, the handleAction function takes the UnitStore and the action and then matches an action handler function if one exists to create a new state, otherwise it will just hand back the original state.

Tests
[<TestClass>]
type StoreTests () =
    member this.createDefaultStore =
        { 
            PlayerStore = 
                { 
                    Players = Map.empty.Add(1, { Id = 1; Name = "Player1"; Cash = 0; CurrentSelection = [] })
                    CurrentTime = 0.0
                }
            UnitStore =
                {
                    Units = Map.empty
                    CurrentGameObjectId = 0
                    CurrentTime = 0.0 
                }
        }
For starters, we define a function that creates the initial GameState that will be used by all of our tests.
    [<TestMethod>]
    member this.StoreTests_GameState_UnknownType () =
        let originalState = this.createDefaultStore
        let action = 1
        let newState = GameState.handleAction originalState action
        Assert.AreEqual(originalState, newState)
First test, just check that if we send in an unknown action, we get back the original state object, nothing changed, the exact same object.
    [<TestMethod>]
    member this.StoreTests_GameState_UpdatePlayerStore () =
        let originalState = this.createDefaultStore
        let action = { Player = 1; Amount = 10 }
        let newState = GameState.handleAction originalState action
        Assert.AreNotEqual(originalState, newState)
        Assert.AreEqual(originalState.UnitStore, newState.UnitStore)
        Assert.AreEqual(10, newState.PlayerStore.Players.[1].Cash)
Secondly we test that an action that should update 1 store, does that, but leaves the other stores unchanged.
    [<TestMethod>]
    member this.StoreTests_GameState_UpdateMultipleStores () =
        let originalState = this.createDefaultStore
        let action = { Time = 22.0; Delta = 0.015 }
        let newState = GameState.handleAction originalState action
        Assert.AreNotEqual(originalState, newState)
        Assert.AreEqual(22.0, newState.PlayerStore.CurrentTime)
        Assert.AreEqual(22.0, newState.UnitStore.CurrentTime)
The last test just verifies that an action can be handled by multiple Stores.

Finally

There are probably a lot of things that could be written in a better way, I am still learning F# and finding new ways to do things daily. Overall I find that this language has nice constructs for many of the things I tried to do with C# when I tried functional constructs there. A lot less plumbing here as the language has built in support for many of the things, lets one focus on actually writing functionality instead of plumbing code. I am glad that I tried this out : )

All code provided as-is. This is copied from my own code-base, May need some additional programming to work. Use for whatever you want, how you want! If you find this helpful, please leave a comment, not required but appreciated! :)

Hope this helps someone out there!

Tuesday, March 13, 2018

Functional Adventures in F# - Using Map Collections


This time we will look at how we can manipulate Map collections to store data.

This post is part of a series:
Functional Adventures in F# - A simple planner
Functional Adventures in F# - Calling F# from C#
Functional Adventures in F# - Using Map Collections
Functional Adventures in F# - Application State
Functional Adventures in F# - Types with member functions
Functional Adventures in F# - Getting rid of loops
Functional Adventures in F# - Getting rid of temp variables
Functional Adventures in F# - The MailboxProcessor
Functional Adventures in F# - Persisting Application State
Functional Adventures in F# - Adding Snapshot Persisting
Functional Adventures in F# - Type-safe identifiers
Functional Adventures in F# - Event sourcing lessons learned

I am no expert in F#, writing these posts is a way for me to learn and hopefully they can help someone else as well.

Graph of symbols

OK, so I want to create a symbol graph (influenced by some ideas in the book 'Gödel, Escher, Bach: An Eternal Golden Braid', a book I really recommend everyone to read)
This is just a very naive implementation but it raised some issues when dealing with F# in general.
Basic concept is that you have a bunch of symbols and each time they are triggered together with another symbol you either add an edge or increase the edges weight. And when 2 symbols are totally interlinked, they may become a new symbol of their own. But in this example I will just focus on the graph bit.

Defining types with and keyword

For example: In F#, everything that you use need to be defined before you use them. Meaning that if you have type X that references type Y, and then type Y reference type X.. You have a problem.
type X = { name:string; hits:int; outgoingEdges:Y}
type Y = { target:X; hits:int;  }
This would result in a "The type 'Y' is not defined." error. To solve it, we can change the second type definition to use the keyword and instead of type.
type X = { name:string; hits:int; outgoingEdges:Y}
and Y = { target:X; hits:int;  }

Lets start with defining some types.
module Symbolism =
    type Edge = { targetName:string; hits:int;  }
    type Symbol = { name:string; hits:int; outgoingEdges:Edges}
    and Edges = Map<string, Edge>
    type Symbols = Map<string, Symbol>
So here we see the usage of the and keyword as Symbol forward references Edges.

Using Map Collections

As you can see above, we have defined Edges and Symbols to be of the type Map, basically Map works like a Dictionary in C#, there are probably differences (other then the immutability part), but for my purposes I like to think that they are about the same. They both store objects as Key/Value pairs.

So, our first function will be getSymbol that takes a Symbols collection and the name of the symbol to get. Here I want to return the symbol from the Map if it exists, otherwise return a new empty symbol that has never been seen before. For this we will use pattern matching mechanism of F#, the task is quite trivial and thus a straight forward place to figure out how pattern matching works.
let getSymbol (symbols:Symbols) (key:string) =
    match symbols.ContainsKey key with
    | true -> symbols.[key]
    | _ -> { name = key; hits = 0; outgoingEdges = Map.empty }
We start by checking if they Symbols Map contains the key with the match [expression] with part.
The next line we define what happens if the result is true. We return the object that is in the Map, notice the dot (.) before the indexer. In C# you would access a dictionary as 'symbols[key]' but in F# you need the extra dot.
The second pattern line means, anything else.... So in this case it would be if the result is false we return a brand new record. The outgoingEdges is of the type Edges that is a Map<string, Edge>. I spent some time trying to initialize it with Edges.empty until I figured out that it is the Map.empty that should be used to initialize an empty map of any type.

Next, we want to add or update a value in the Map.
let addEdgeToSymbol (symbol:Symbol) (target:Symbol) = 
    let edge = getEdge symbol target
    let weightedEdge = increaseEdgeWeigth edge
    let updatedSymbol:Symbol = { symbol with outgoingEdges = symbol.outgoingEdges.Add(target.name, weightedEdge) }
    updatedSymbol
This took me a while as well. Trying to google how to update a value in a Map collection. Evidently it is built into the Add function.
If the key does not exist in the Map: a new Map with the key/value pair added to it is returned
If the key exists already in the Map: a new Map with the value in the key location updated is returned.
Pretty neat to not have to bloat the code with all the checks just to add or update, just call the Add function.
Here also, we want to update one field in the symbol record. We could define a new record and manually copy all the fields but that is just code debt waiting to blow. Instead there is a nice way to do this with the following line.
{ symbol with outgoingEdges = symbol.outgoingEdges.Add(target.name, weightedEdge) }
Here we say, that we want a new record based on the values in the record 'symbol' but with the following things updated. In this case the outgoingEdges field.

Full source code

module Symbolism =
    type Edge = { targetName:string; hits:int;  }
    type Symbol = { name:string; hits:int; outgoingEdges:Edges}
    and Edges = Map<string, Edge>
    type Symbols = Map<string, Symbol>
        
    let getSymbol (symbols:Symbols) (key:string) =
        match symbols.ContainsKey key with
        | true -> symbols.[key]
        | _ -> { name = key; hits = 0; outgoingEdges = Map.empty }
    
    let getEdge (symbol:Symbol) (target:Symbol) = 
        match symbol.outgoingEdges.ContainsKey target.name with
        | true -> symbol.outgoingEdges.[target.name]
        | _ -> { targetName = target.name; hits = 0; }

    let increasSymboleWeigth symbol:Symbol =
        let updatedSymbol:Symbol = { symbol with hits = symbol.hits + 1 }
        updatedSymbol

    let increaseEdgeWeigth edge:Edge =
        let updatedEdge:Edge = { edge with hits = edge.hits + 1 }
        updatedEdge
        
    let addEdgeToSymbol (symbol:Symbol) (target:Symbol) = 
        let edge = getEdge symbol target
        let weightedEdge = increaseEdgeWeigth edge
        let updatedSymbol:Symbol = { symbol with outgoingEdges = symbol.outgoingEdges.Add(target.name, weightedEdge) }
        updatedSymbol

    let addEdge (symbols:Symbols) (from:string) (target:string) = 
        let symbol = getSymbol symbols from
        let targetSymbol = getSymbol symbols target
        let edgedSymbol = addEdgeToSymbol symbol targetSymbol
        let weightedSymbol = increasSymboleWeigth edgedSymbol
        let weightedTargetSymbol = increasSymboleWeigth targetSymbol
        symbols
            .Add(from, weightedSymbol)
            .Add(target, weightedTargetSymbol)

Unit tests

[<TestClass>]
type SymbolismTest () =

    [<TestMethod>]
    member this.Symbolism_getSymbol_NoExistingSymbols () =
        let target : Symbols = Map.empty
        let actual = getSymbol target "ewan mcgregor"
        Assert.AreEqual("ewan mcgregor", actual.name)
        Assert.AreEqual(0, actual.outgoingEdges.Count)
  
  
    [<TestMethod>]
    member this.Symbolism_getSymbol_ExistingSymbol () =
        let target : Symbols = Map.empty.Add("ewan mcgregor", { name = "test item"; hits = 0; outgoingEdges = Map.empty })
        let actual = getSymbol target "ewan mcgregor"
        Assert.AreEqual("test item", actual.name)
        Assert.AreEqual(0, actual.outgoingEdges.Count)
        
    [<TestMethod>]
    member this.Symbolism_addEdgeToSymbol () =
        let from = { name = "daisy ridley"; hits = 0; outgoingEdges = Map.empty }
        let target = { name = "star wars"; hits = 0; outgoingEdges = Map.empty }
        let actual = addEdgeToSymbol from target
        Assert.AreEqual("daisy ridley", actual.name)
        Assert.AreEqual(1, actual.outgoingEdges.Count)
        Assert.IsTrue(actual.outgoingEdges.ContainsKey("star wars"))
        Assert.AreEqual(1, actual.outgoingEdges.["star wars"].hits)
        
    [<TestMethod>]
    member this.Symbolism_addEdge_NoExistingSymbols () =
        let target : Symbols = Map.empty
        let symbols = addEdge target "ewan mcgregor" "star wars"
        let actualewan = getSymbol symbols "ewan mcgregor"
        let actualStarWars = getSymbol symbols "star wars"
        Assert.AreEqual("ewan mcgregor", actualewan.name)
        Assert.AreEqual(1, actualewan.hits)
        Assert.AreEqual(1, actualewan.outgoingEdges.Count)
        Assert.AreEqual("star wars", actualStarWars.name)
        Assert.AreEqual(1, actualStarWars.hits)
        Assert.AreEqual(0, actualStarWars.outgoingEdges.Count)
        Assert.AreEqual(2, symbols.Count)

Here in the Symbolism_getSymbol_ExistingSymbol test we can see how to initialize a Map with a starting key value. I.e. by adding an item to an empty Map.



Merging 2 Map collections

Added 2018-03-21, did not want to create a new post for this.
At some point you may come across a problem that needs to be solved by merging 2 different Map collections that have the same type if Key and Value. To use this, we will use Map.fold to create a new Map collection that has the contents of both input Maps
let newUnits = Map.fold (fun acc key value -> Map.add key value acc) state.Units builtUnits




So there it is. We have gone through how to
  • Check if a key exists in a Map
  • Retrieve the value stored in the Map for a particular key
  • Add values to a Map
  • Update values in a Map
  • Initialize an empty Map
  • Initialize a Map with key/value pairs from the start
  • Merge 2 Map collections
All code provided as-is. This is copied from my own code-base, May need some additional programming to work. Use for whatever you want, how you want! If you find this helpful, please leave a comment or share a link, not required but appreciated! :)

Hope this helps someone out there!

Sunday, March 11, 2018

Functional Adventures in F# - Calling F# from C#


I have quite a lot of code lying around that is written in C# and going into a new project, the most natural is to start with C# as the core application. Now when I am exploring the functional paradigm with F#, I still want to be able to call all the F# code from C#. In other words, the most natural is to add new functionality to my existing applications using F# and not try to accomplish the 'everything shall be written in F#' utopia.

This post is part of a series:
Functional Adventures in F# - A simple planner
Functional Adventures in F# - Calling F# from C#
Functional Adventures in F# - Using Map Collections
Functional Adventures in F# - Application State
Functional Adventures in F# - Types with member functions
Functional Adventures in F# - Getting rid of loops
Functional Adventures in F# - Getting rid of temp variables
Functional Adventures in F# - The MailboxProcessor
Functional Adventures in F# - Persisting Application State
Functional Adventures in F# - Adding Snapshot Persisting
Functional Adventures in F# - Type-safe identifiers
Functional Adventures in F# - Event sourcing lessons learned

So, first off. We need to give our C# project the knowledge of F# types. So lets Nuget the FSharp.Core package and we are all set!

After that, calling the F# code from C# is easy. Lets use the code that we wrote in the last post with the Planner module.

We had 2 different types described in the module, the ScheduledAction that was a record type and the Schedule that was a list of ScheduledActions.

Lets look at some code:
using System;
using Microsoft.FSharp.Collections;

namespace app.Components
{
    public class Main
    {
        private FSharpList<Planner.ScheduledAction> _schedule;
        public bool Shutdown { get; set; }

        public void MainLoop()
        {
            while (!Shutdown)
            {
                var executableActions = Planner.getExecutableActions(DateTime.UtcNow, _schedule);
                foreach (var action in executableActions)
                {
                    Execute(action);
                    _schedule = Planner.removeFromSchedule(action, _schedule);
                }
            }
        }

        private void Execute(Planner.ScheduledAction action)
        {
            // execute business logic here
        }
    }
}

As you an see, the Schedule type did not follow through as I expected. It is exposed a FSharpList<ScheduledAction>, i.e. we need to write the whole thing instead of just using Schedule. Other then that there seems to be nothing strange here. Planner is identified by intellisense as a class.

If we try to modify the name of the ScheduledAction that we have received from the F# code, the code will not compile but instead show you the error
Property or indexer 'Planner.ScheduledAction.name' cannot be assigned to -- it is read only
This is due to that everything defined in F# is immutable (well almost everything).
So that is that, it just reference the FSharp.Core and your F# project from your C# project and you are good to go.

All code provided as-is. This is copied from my own code-base, May need some additional programming to work. Use for whatever you want, how you want! If you find this helpful, please leave a comment, not required but appreciated! :)

Hope this helps someone out there!

Sunday, March 4, 2018

Functional Adventures in F# - A simple planner


Last year when I got sick I bought the openGL Bible and started writing about graphics programming with openTK in C# just to keep my mind occupied.
This year things turned bad again, so a new book... This time it is time for F# as I got really curious about functional programming during the last few months.

This post is part of a series:
Functional Adventures in F# - A simple planner
Functional Adventures in F# - Calling F# from C#
Functional Adventures in F# - Using Map Collections
Functional Adventures in F# - Application State
Functional Adventures in F# - Types with member functions
Functional Adventures in F# - Getting rid of loops
Functional Adventures in F# - Getting rid of temp variables
Functional Adventures in F# - The MailboxProcessor
Functional Adventures in F# - Persisting Application State
Functional Adventures in F# - Adding Snapshot Persisting
Functional Adventures in F# - Type-safe identifiers
Functional Adventures in F# - Event sourcing lessons learned

So previous experience with functional ideas are from web tech like Redux and writing the core engine of my latest game project in C# with functional constructs. If you want to know more about that project you can read here:
Functional adventures in .NET C# - Part 1, Immutable Objects
Functional adventures in .NET C# - Part 2, Application State

So, next step is to actually use a language that is built for this. And luckily in .NET there is a full featured one.

At first I thought about converting a already existing piece of C# to F# to see the similarities and differences but I quickly omitted that idea. So for the next few posts I will try to write a Scheduler with F#.

If you do not have any development environment, please check out Visual Studio Community Edition, it is a great and free environment that I use for my private projects. It has support for F#.

Defining data

As a first step we need to define the different types of data that we have.

Step 1, decide if we should use CLI types or F# specific types.

CLI Types: Standard types that can be used in all .NET languages
F# Types: Specific to F#, cannot be used outside. Designed with functional paradigm in mind and does not have null and are immutable. They also have built in equality checking and pretty printing.

Our choice here will be F# types to be able to use the language to its full extent as it was designed.
As a starter, we want to be able to build a collection of planned Actions. So lets first define what we will be planning.
type ScheduledAction = { time:DateTime; name:string; }
This pretty much describes a new Record type that has a time and a name.
Next lets define the Schedule as an ImmutableSortedSet
type Schedule = ScheduledAction list
Nothing fancy here either, as you can see compared to C# the order of things is switched, where we would write list<ScheduledAction> we just write ScheduledAction litinstead. I think you can use the C# notation as well but I am trying to stick with the way my book says is the F# way.

Adding functionality

Next we will want to add a ScheduledAction to the current Schedule. As everything is immutable we will define a function that takes the new ScheduledAction and the current Schedule, and returns a new Schedule with the ScheduledAction added to it. We will not change the current Schedule, just return a new Schedule with the change made to it.
So just add a new item.
let schedule (action:ScheduledAction) (currentPlan:Schedule) =
    let newPlan = action :: currentPlan
    newPlan
Here we define the function schedule that takes 2 arguments: action and currentPlan. The parenthesis are not needed if you do not supply the type arguments. But my compiler complained (FS0613 Syntax error in labelled type argument) if I didn't add them so hence the parenthesis.
The item :: tail construct takes an item and a list and returns a new list with the item as the first item and the tail as ... the tail.

Next step is to retrieve actions that should be executed. So lets define a new function, this will not change the plan, just return a new list with items that should be executed.
let getExecutableActions (currentTime:DateTime) (currentPlan:Schedule) =
    let actions = List.filter (fun x -> x.time <= currentTime) currentPlan
    actions
Here we use the List.filter function to apply a filter to each item in the list. As Schedule is a list this works fine.

Finally we want to remove items that have been executed (in some way, outside of scope here).
let removeFromSchedule (action:ScheduledAction) (currentPlan:Schedule) =
    let newPlan = List.filter (fun x -> compare x action <> 0) currentPlan
    newPlan
Basically the method is the same as the above, but it compares each element in the list to the one we want to remove, and if it is the one we want to remove, we just do not add it to the new list. I.e. filter it away.

The complete planner module

namespace scheduler

module Planner =
    open System
    type ScheduledAction = { time:DateTime; name:string;}
    type Schedule = ScheduledAction list

    let schedule (action:ScheduledAction) (currentPlan:Schedule) =
        let newPlan = action :: currentPlan
        newPlan

    let getExecutableActions (currentTime:DateTime) (currentPlan:Schedule) =
        let actions = List.filter (fun x -> x.time <= currentTime) currentPlan
        actions

    let removeFromSchedule (action:ScheduledAction) (currentPlan:Schedule) =
        let newPlan = List.filter (fun x -> compare x action <> 0) currentPlan
        newPlan
So here we have the complete planner in 18 lines of code.

Adding unit tests

Of course we should have unit tests to ensure correct functionality. Luckily F# makes it quite easy to write tests as well.
namespace scheduler.tests

open System
open Microsoft.VisualStudio.TestTools.UnitTesting
open scheduler
open scheduler.Planner

[<TestClass>]
type PlannerTests () =

    [<TestMethod>]
    member this.Planner_schedule_AddItemToEmptySchedule () =
        let item : ScheduledAction = { time = DateTime.UtcNow; name = "first item" }
        let target : Schedule = []
        let newSchedule = schedule item target
        Assert.AreEqual(item, newSchedule.Head);
  
    [<TestMethod>]
    member this.Planner_schedule_AddItemToNonEmptySchedule () =
        let item : ScheduledAction = { time = DateTime.UtcNow; name = "first item" }
        let item2 : ScheduledAction = { time = DateTime.UtcNow; name = "second item" }
        let target : Schedule = []
        let intermediateSchedule = schedule item target
        let newSchedule = schedule item2 intermediateSchedule
        Assert.AreEqual(item2, newSchedule.Head);
        Assert.AreEqual(2, newSchedule.Length);

For the schedule function, we add 2 tests, one that adds a new item to an empty Schedule, and one that adds an extra item to a Schedule that already has items.
       
    [<TestMethod>]
    member this.Planner_getExecutableActions_EmptySchedule () =
        let target : Schedule = []
        let actual = getExecutableActions DateTime.UtcNow target
        Assert.AreEqual(0, actual.Length);

   
    [<TestMethod>]
    member this.Planner_getExecutableActions_SingleItemSchedule_NoExecutable () =
        let currentTime = DateTime.UtcNow;
        let item : ScheduledAction = { time = currentTime; name = "first item" }
        let target : Schedule = []
        let newSchedule = schedule item target
        let currentTime = currentTime.AddSeconds(-2.0);
        let actual = getExecutableActions currentTime newSchedule
        Assert.AreEqual(0, actual.Length);
 
 
    [<TestMethod>]
    member this.Planner_getExecutableActions_SingleItemSchedule_SingleExecutable () =
        let currentTime = DateTime.UtcNow;
        let item : ScheduledAction = { time = currentTime; name = "first item" }
        let target : Schedule = []
        let newSchedule = schedule item target
        let currentTime = currentTime.AddSeconds(2.0);
        let actual = getExecutableActions currentTime newSchedule
        Assert.AreEqual(1, actual.Length);

    [<TestMethod>]
    member this.Planner_getExecutableActions_MultiItemSchedule_SingleExecutable () =
        let currentTime = DateTime.UtcNow;
        let item : ScheduledAction = { time = currentTime.AddYears(1); name = "first item" }
        let item2 : ScheduledAction = { time = currentTime; name = "second item" }
        let target : Schedule = []
        let intermediateSchedule = schedule item target
        let newSchedule = schedule item2 intermediateSchedule
        let currentTime = currentTime.AddSeconds(2.0);
        let actual = getExecutableActions currentTime newSchedule
        Assert.AreEqual(item2, actual.Head);
        Assert.AreEqual(1, actual.Length);
For the getExecutableActions function we add 4 tests.

  • One that checks so that the special case of an empty Schedule is handled correctly. 
  • Secondly that the time filter is correct when we have a single item in the list that is not OK to execute yet. 
  • Thirdly a single item that is OK to execute
  • and lastly a Schedule with multiple items with 1 able to execute and 1 not able to

    [<TestMethod>]
    member this.Planner_removeFromSchedule_RemoveItem () =
        let item : ScheduledAction = { time = DateTime.UtcNow; name = "first item" }
        let item2 : ScheduledAction = { time = DateTime.UtcNow; name = "second item" }
        let target : Schedule = []
        let intermediateSchedule = schedule item target
        let newSchedule = schedule item2 intermediateSchedule
        let actual = removeFromSchedule item newSchedule
        Assert.AreEqual(item2, actual.Head);
        Assert.AreEqual(1, actual.Length);
And lastly we check that removeFromSchedule function does just that, removes the item we want to remove and leaves the rest in the list. (in the new list that is returned, the original is not changed... remember immutable)


All code provided as-is. This is copied from my own code-base, May need some additional programming to work. Use for whatever you want, how you want! If you find this helpful, please leave a comment, not required but appreciated! :)

Hope this helps someone out there!

Sunday, October 1, 2017

Functional adventures in .NET C# - Part 2, Application State


This part we will look at how to store and manipulate application/game state in an ordered fashion. This is heavily inspired by the React/Redux web development (javascript) patterns. My thoughts were, why not use the same in my game code as the end results are pretty clean and structured?

This is part 2 of this series. Here are links to all the other posts:
Functional adventures in .NET C# - Part 1, Immutable Objects
Functional adventures in .NET C# - Part 2, Application State

Update 2018-03-15: I only wrote 2 posts on C# functional constructs. And after embarking on a large game project with it I started looking at F#. To read the F# source code of this post, head over to Functional Adventures in F# - Application State

General Idea

At any given point in time, the whole application state is stored in a class named Application State, it consists of different Stores and they in turn consist of the object model for each store. I.e. Fleet Store might contain Fleets that consists of Ships. All updates to the model are routed to the store in the form of Actions. The application state is immutable, meaning that any object that you get a reference to will never mutate into something else (see previous post in this series on Immutable objects)

Add object to a store
Say that you would like to create a new object in Store Y, this would yield in a new instance of Store Y that also contains the new object. And as Store Y belongs to Application State, it would need a new instance of that as well. That still point to the old instances of Store X & Z but a new instance of Y.

Update object in a store
If you in turn would like to update a object that is deeper in the structure inside Store Z, you would create a copy (call the Modify method) on that object. But as it returns a new object, you would have to propagate the change to the parent object (SetItem if it is in the System.Collections.Immutable namespace, or Modify if it is our own) and then propagate it to a new version of the application state object as well.

Remove object from a store
And it is pretty much the same for when you want to remove objects, you remove the object reference from the parent object by calling Remove or Modify depending on if it is a collection or our own object. And then you propagate the change up all the way to a new Application State object.


Code

So, now that we know the general idea lets look at some code. At the moment I decided to only propagate the change to the store and let the ApplicationState class be the entry point to the different stores. So not 100% immutable, only where it counts.. I.e. the model.

Application State

The ApplicationState (or GameState in this case) contains references to all the different stores.
public static class GameState
{
    private static FleetStore _fleetStore;

    public static FleetStore FleetStore
    {
        get
        {
            if(_fleetStore == null)
                _fleetStore = new FleetStore();
            return _fleetStore;
        }
        set
        {
            _fleetStore = value;
        }
    }
}
I decided to have this globally accessible so that the whole game can read the current application state  and dispatch actions from this static context.

Actions

Actions are pretty much POCOs (plain old class objects)
public class CreateFleet
{
    public string Name { get; }
    public CreateFleet(string name)
    {
        Name = name;
    }
}
These are safe objects, if any part of the application wants to change state they are not allowed to call the modify method by themselves. Even if they did they would not be able to propagate the change properly so that it becomes visible. Instead they create an Action object describing the change that they want to be done and send it to the Store.

Stores and Action Handlers

The store holds the immutable state of its model and handles all actions.
First of, lets look at the abstract base class for all of the stores.
public abstract class AStore<TItem>
{
 public ImmutableList<TItem> State { get; protected set; }
 private ImmutableDictionary<Type, Action<object>> _actionHandlers;
 private readonly object _lock = new object();
 public AStore()
 {
  State = ImmutableList<TItem>.Empty;
  _actionHandlers = ImmutableDictionary<Type, Action<object>>.Empty;
 }

 public void HandleAction(object action)
 {
  lock (_lock)
  {
   var actionType = action.GetType();
   var handlers = _actionHandlers;
   if (handlers.TryGetValue(actionType, out var actionHandler))
   {
    actionHandler(action);
   }
  }
 }

 public void HandleActionAsync(object action)
 {
  ThreadPool.QueueUserWorkItem(HandleAction, action);
 }

 protected void AddActionHandler(Type actionType, Action<object> actionHandler)
 {
  _actionHandlers = _actionHandlers.Add(actionType, actionHandler);
 }
}

First of, we have the State stored as a ImmutableList<T>, all changes to objects managed by this store will propagate to this State object and replace it with a new reference. The State is public and is read by the rest of the application.

Secondly we have a dictionary of Action Handlers. Here we can lookup the correct action handler with the help of the Type of the action.

There is only 2 public methods, HandleActionAsync. All it does is to dispatch the action to the threadpool.
The HandleAction is pretty basic, it tries to get an action handler for the object type it received and either dispatches the action to the correct handler or does nothing. All this is done inside a lock to ensure that only 1 thread is writing at a time.
I am not 100% satisfied with this solution to serialize the writes, if you have a better solution please do not hesitate to share in the comments!

There is also only 1 protected method, AddActionHandler. This is used by all sub-classes that inherit from this abstract class to register action handlers that are defined in their code.

Example of concrete store. In this case taken from my space game.
public class FleetStore : AStore<Fleet>
{
 private uint _currentFleetId;
 private uint _currentShipId;
 public FleetStore()
 {
  AddActionHandler(typeof(CreateFleet), CreateFleet);
  AddActionHandler(typeof(RemoveFleet), RemoveFleet);
  AddActionHandler(typeof(CreateShip), CreateShip);
  AddActionHandler(typeof(MoveShipToFleet), MoveShipToFleet);
  AddActionHandler(typeof(SetShipTargetVector), SetShipTargetVector);
 }
Here we see that in the constructor the class registers all action handlers with the help of the AddActionHandler method.

Example of Add action handler
private void CreateFleet(object action)
{
 var a = (CreateFleet) action;
 var fleet = Fleet.Default.Modify(_currentFleetId++, a.Name);
 State = State.Add(fleet);
}
Here we use the Fleet.Default reference (instead of calling new) to create a new immutable fleet and then call Add on the State list. And finally replace the State with the new State so that it sticks.

Example of Remove action handler
private void RemoveFleet(object action)
{
 var a = (RemoveFleet)action;
 var item = State.FirstOrDefault(x => x.Id == a.Id);
 State = State.Remove(item);
}
Here we find the item to remove with a query and then call Remove on the state list and replace the old state with the new state.

And finally an example of Update action handler
private void SetShipTargetVector(object action)
{
 var a = (SetShipTargetVector)action;
 var originalFleet = State.FirstOrDefault(x => x.Id == a.FleetId);
 var originalShip = originalFleet.Ships.FirstOrDefault(x => x.Id == a.ShipId);
 
 var ship = originalShip.Modify(targetCoordinates: a.Target);
 var ships = originalFleet.Ships.SetItem(originalFleet.Ships.IndexOf(originalShip), ship);
 var fleet = originalFleet.Modify(ships: ships);
 State = State.SetItem(State.IndexOf(originalFleet), fleet);
}
This is an update of a field a little bit deeper in the object structure.
First we need to find the Fleet from the state list.
After that we find the ship from the fleets list of ships.
Then we modify the ship and store the new state in a new variable.
Then we use the old ship to find the index in the list that we want to replace with the new ship. We store the new immutable list in a new variable.
After that we modify the fleet and set the new list of ships with the Modify command and store the new fleet.
Lastly we update the State with SetItem and replace the old State with the new one.


Hope this helps someone out there getting started with immutable application state in C#, or at least getting some new ideas. Thank you for reading, here's a video of one of our cats

Saturday, September 30, 2017

Functional adventures in .NET C# - Part 1, immutable objects


Lately I've been converted to the immutable data train, working with web technologies like React/Redux. I've started to wonder why I don't build all applications with immutable data, as it removes a big headache, if you get a reference to a data structure it will _always_ be the same data in it. Not like when you are working with ordinary data structures, where other threads or sub-functions can modify the in data when you aren't looking.

This is part 1 of this series. Here are links to all the other posts:
Functional adventures in .NET C# - Part 1, Immutable Objects
Functional adventures in .NET C# - Part 2, Application State

So, my native platform is .NET and C#, is there a way to work with immutable data out of the box or do we have to write something ourselves? It turns out that Microsoft has released an immutable library System.Collections.Immutable outside of the ordinary .NET versions as a NuGet package.
It has all the collections like
  • System.Collections.Immutable.ImmutableArray
  • System.Collections.Immutable.ImmutableArray<T>
  • System.Collections.Immutable.ImmutableDictionary
  • System.Collections.Immutable.ImmutableDictionary<TKey,TValue>
  • System.Collections.Immutable.ImmutableHashSet
  • System.Collections.Immutable.ImmutableHashSet<T>
  • System.Collections.Immutable.ImmutableList
  • System.Collections.Immutable.ImmutableList<T>
  • System.Collections.Immutable.ImmutableQueue
  • System.Collections.Immutable.ImmutableQueue<T>
  • System.Collections.Immutable.ImmutableSortedDictionary
  • System.Collections.Immutable.ImmutableSortedDictionary<TKey,TValue>
  • System.Collections.Immutable.ImmutableSortedSet
  • System.Collections.Immutable.ImmutableSortedSet<T>
  • System.Collections.Immutable.ImmutableStack
  • System.Collections.Immutable.ImmutableStack<T>
All well and good! But what of the all the POCO (plain old class object) and domain objects in your code? These need to be converted to immutables as well if you are to build something that can be relied upon.

So, how to do this in a simple way? After searching a bit on how other people are doing this I found this article by @davepermen and decided to take some of the ideas from there.

So here is the pattern that I'm currently using in a space game that I'm writing on my spare time.
public class Fleet
{
    public static Fleet Default { get; } = new Fleet();

    public uint Id { get; }
    public string Name { get; }
    public ImmutableDictionary<ShipType, ImmutableList<Ship>> Ships { get; }
        
    private Fleet()
    {
        Ships = ImmutableDictionary<ShipType, ImmutableList<Ship>>.Empty;
    }
    private Fleet(uint id, string name, ImmutableDictionary<ShipType, ImmutableList<Ship>> ships)
    {
        Id = id;
        Name = name;
        Ships = ships;
    }

    public Fleet Modify(uint? id = null,
        string name = null, 
        ImmutableDictionary<ShipType, ImmutableList<Ship>> ships = null)
    {
        return new Fleet
        (
            id ?? Id,
            name ?? Name,
            ships ?? Ships
        );
    }
}

Some key points.
Private constructor
The constructors are private, as the class is immutable, there is no real reason to have multiple 'new' fleet objects, just get the reference to the Default object.
So to create a new fleet we would do something like:
var fleet = Fleet.Default.Modify(_currentFleetId++, a.Name);
I.e. we get the reference to the default object and call Modify on it with the stuff that we want to have in our new fleet object.

All public fields are getters only
So that you can read the values from outside, but not set them other then from the constructor.

The Modify(T name = null) method
The only way to 'modify' state is to create use this method, and it does not really modify the state but it creates a new state based on the input. All attributes are nullable and with default values so that you only need to specify the values that change. The non-provided values will be copied from this object.
I.e. setting only the name would be like this:
fleet = fleet.Modify(name: "Battlestar!");

Explicit set to null methods
If you need to be able to set a value specifically to null, you would have to create a specific Modify method for that value, as if you send in null to the one provided it would copy the value from this instead of setting it to null.

public Ship RemoveTargetCoordinates()
{
    return new Ship
    (
        Id,
        Coordinates,
        ShipType,
        Health,
        MaxSpeed,
        Acceleration,
        Deceleration,
        null
    );
}
In this example we provide a copy from the current instance of all values but the one we want to set to null. Not the prettiest solution but works for now.

Update 20171003
There is no need to set to null, set the value to Default instead and instead of doing a null check check against the Default value. This solved all my 'set to null' issues in my code base so far. And this way there will not be a null reference exception in the middle of a chained function call.

Hope this helps someone out there getting started with functional programming in C#