Thursday, March 22, 2018

Functional Adventures in F# - Getting rid of temp variables


This time we will look at how to get rid of temporary variables when updating an object in multiple steps.

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

In my game that I am trying to write with F# (at least the core model) I have some functions that look like the following
static member HandleTick (state:UnitStore) (action:Tick) =     
 let queueUpdatedState = UnitStore.handleTickBuildQueues state action
 let unitsUpdatedState = UnitStore.handleTickUnitUpdates queueUpdatedState action
 unitsUpdatedState
A function that takes a state and an action and in turn it uses other functions to update that state with the help of the action.
I don't know, but I grew tired of naming temporary variables after a while and started googling for a better solution. Turns out there is one. By using the forward-pipe operator '|>' we can take the output of one function and send it as input to the next function.

static member HandleTick (state:UnitStore) (action:Tick) =     
 UnitStore.handleTickBuildQueues action state 
 |> UnitStore.handleTickUnitUpdates action
To make this work, the order of parameters need to be switched so that Action is the first argument followed by the State.
Turns out I have to refactor all the functions in my Stores to take the action first and state as second argument to get this working, but I guess that is a small price to pay for cleaner code.

Looking at the assembly in ILSpy gives us that in the background there will be temporary variables passed around, but our code is clean of them.
public static UnitStore HandleTick(Actions.Tick action, UnitStore state)
{
 UnitStore unitStore = UnitStore.handleTickBuildQueues(action, state);
 UnitStore state2 = unitStore;
 return UnitStore.handleTickUnitUpdates(action, state2);
}

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!
Until next time: Work to Live, Don’t Live to Work

Wednesday, March 21, 2018

Functional Adventures in F# - Getting rid of loops


Solving problems without loops.....

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

This time lets look at a real issue when coming from an imperative language and trying functional programming.
The example problem (that I crashed into when rewriting some game logic in F#) is that of spawning new Ships in a space game. We do not want to spawn 2 ships on top of each other, so we generate the default spawning coordinate and then test if it is safe to use, if not we move the ship a bit and try again....

How I solved it in C#..
private Ship FindClosestFreeCoordinate(ImmutableList<Fleet> state, Ship newShip)
{
    var shipsWithinSafetyDistance = ShipsWithinSafetyDistance(state, newShip);
    while (shipsWithinSafetyDistance.Any())
    {
        var newCoordinates = newShip.Coordinates.Position.Add(Vector3.UnitXVector);
        newShip = newShip.Modify(coordinates: newShip.Coordinates.Modify(position: newCoordinates));
        shipsWithinSafetyDistance = ShipsWithinSafetyDistance(state, newShip);
    }
    return newShip;
}

private List<Ship> ShipsWithinSafetyDistance(ImmutableList<Fleet> state, Ship newShip)
{
    return (from fleet in state
        from
            ship in fleet.Ships
        where
            ship.Distance(newShip) < 5
        select ship).ToList();
}

Translating the ShipsWithinSafetyDistance function is no problem. We just use the Map.filter function...
static member private shipsWithinSafetyDistance (unit:Unit) (state:UnitStore) =
    Map.filter (fun key value -> unit.distanceToUnit value < 5.0) state.Units
Ah, yes.. I switched from a ImmutableList in C# to a Map in F#, just to keep things interesting (and to get faster Key lookups)


So, the tricky part here is the while loop. Most loops can be rewritten with Map/List functions like map, filter and fold etc... But this time I don't see how to use them as I don't have a Collection of any sort here so my brain keeps yelling "Write a loooooop", as that is the way I have solved this kind of problems for the past 20+ years... So...
How should we do it in F#??? We have some other constructs to use that fit the functional idea better.

static member private findClosestFreeCoordinate (unit:Unit) (state:UnitStore) =
 let rec findClosestFreeCoordinateRecursive (unit:Unit) (state:UnitStore) = 
  let shipsWithinSafetyDistance = shipsWithinSafetyDistance unit state
  match shipsWithinSafetyDistance with
  | a when a.IsEmpty -> unit
  | _ ->  let newUnit = { unit with Coordinates = unit.Coordinates + Vector3.UnitX }
    findClosestFreeCoordinateRecursive newUnit state
 findClosestFreeCoordinateRecursive unit state
Recursion!
At least for this problem, it seems to be a good option. Here we define a function, findClosestFreeCoordinateRecursive with the rec keyword to let the compiler know that it will be called recursively. In the function body we match the result list with IsEmpty and return the input value or else call the recursive function with a new copy of the unit with new coordinates.

Call stack.. Is there a risk for stack overflow with this?
Lets open the dll output with ILSpy to check what actually goes on behind the scenes
ILSpy of F# Recursive Function
Turns out, that the current F# compiler in the background uses a while loop. The key here is that we do not, instead we define a short and concise function where we state what it is that we want done, how it is solved behind the scene in detail is not up to us. At some point, there is always someone that needs to write the ifs and loops, but lets keep them away from the application code that we write.

So there, lets move the last shipsWithinSafetyDistance to inner scope of our function and we are set
static member private findClosestFreeCoordinate (unit:Unit) (state:UnitStore) =
 let shipsWithinSafetyDistance (unit:Unit) (state:UnitStore) =
  Map.filter (fun _ value -> unit.distanceToUnit value < 50.0) state.Units
 let rec findClosestFreeCoordinateRecursive (unit:Unit) (state:UnitStore) = 
  let shipsWithinSafetyDistance = shipsWithinSafetyDistance unit state
  match shipsWithinSafetyDistance with
  | a when a.IsEmpty -> unit
  | _ ->  let newUnit = { unit with Coordinates = unit.Coordinates + Vector3.UnitX }
    findClosestFreeCoordinateRecursive newUnit state
 findClosestFreeCoordinateRecursive unit state

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!
Until next time: Work to Live, Don’t Live to Work


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


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!
Until next time: Work to Live, Don’t Live to Work