Exploring Functional Approaches to Handling
Indefinite Loops in C#
We’ve seen in previous chapters how functional programming replaces For
and ForEach loops with LINQ functions like Select or Aggregate,
and that’s absolutely terrific - provided you are working with a fixed-length
array, or an Enumerable that will determine for itself when it’s time to
finish iterating.
What do you do though, when you aren’t at all sure how long you’ll want to
iterate for? What if you’re iterating indefinitely until a condition is met?
Here’s an example of some non-functional code that shows the sort of thing
I’m talking about. I’m imagining some code here for a game of Monopoly.
You’re stuck in jail, you naughty individual! The rules for getting out are
doing one of the following:
Pay 50 in whichever currency you play in (Pounds Sterling for me)
Roll a double
Use a “Get out of Jail Free” card1
In a real game of Monopoly, there are other player’s turns to consider, but
I’m simplifying it down to looping indefinitely until one of these conditions
are met. I’d probably add some validation logic in here too if I were doing
this for real, but once again, I’m keeping it simple.
var inJail = true;
var inventory = getInventory();
var rnd = getRandomNumberGenerator();
while(inJail)
{
var playerAction = getAction();
if(playerAction == Actions.PayFine)
{
inventory.Money -= 50;
inJail = false;
}
if(playerAction == Actions.GetOutOfJailFree)
{
inventory.GetOutOfJailFree -= 1;
inJail = false;
}
if(playerAction == Actions.RollDice)
{
var dieOne = rnd.Random(1, 6);
var dieTwo = rnd.Random(1,6);
inJail = dieOne == dieTwo; // get out if a double
}
}
You can’t possibly do the above with a Select statement, it’s simply
not possible. We can’t say when the criteria will be met, and we’ll
continue to iterate around the While loop until one of them are.
How can we do this functional? A While loop is a statement, and as
such not preferred by functional programming languages.
There are a few options, and I’ll describe each of them, but this is one of
those areas where some sort of trade-off is required. Each of the choices
have consequences, and I’ll do my best to consider their respective pros and
cons.
Buckle up your seatbelts, here we go…
Tail Recursion
The classic functional programming method for handling indefinite loops is
to use recursion. In brief, for those of you unfamiliar with it - Recursion is
the use of a function that calls itself. There will be a condition of some sort
too that determines whether there should be another iteration, or whether to
actually return data.
If the decision is made at the end of the recursive function, this is known as
tail recursion.
A purely recusive solution to the Monopoly problem might look like this:
// I'm making the Inventory object a Record to make it
// a bit easier to be functional
var inventory = getInventory();
var rnd = getRandomNumberGenerator();
var updatedInventory = GetOutOfJail(inventory);
private Inventory GetoutOfJail(Inventory oldInv)
{
var playerAction = getAction();
return playerAction switch
{
Actions.PayFine => oldInv with
{
Money = oldInv.Money - 50
},
Actions.GetOutOfJailFree => oldInv with
{
GetOutOfJail = oldInv.GetOutOfJail - 1
},
Actions.RollDice =>
{
var dieOne = rnd.Random(1, 6);
var dieTwo = rnd.Random(1,6);
// return unmodified state, or else
// iterate again
return dieOne == dieTwo
? oldInv
: GetOutOfJail(oldInv);
}
};
}
Job done, right? Not really, and I would think very carefully before using a
function like the one above. The issue is that every nested function call adds
a new item onto the Stack in the .NET runtime, and if there are a lot of
recursive calls, then that can either negatively effect performance or else kill
the application with a Stack Overflow Exception.
If there are guaranteed only to be a handfull of iterations, then there’s
nothing fundamentally wrong with the recursive approach. You’d also have
to be sure that this is revisited if the code’s usage is ever significantly
changed following an enhancement. It could turn out that this rarely used
function with a few iterations one day turns into something heavily used with
hundreds of iterations. If that ever happens, then the business might wonder
why their wonderful application suddenly becomes near unresponsive almost
overnight.
So, like I said, think very carefully. This has the advantage of being relatively
simple and not requiring you to write any boilerplate to make it happen.
F#, and many other more strongly functional languages, have a feature called
Tail Optimised Recursion Calls, which means it’s possible to write recursive
functions without them exploding the stack. This isn’t available in C#
however, and there are no plans to make it available in the future, either.
Depending on the situation, the F# optimization will either create
Intermediate Language (IL) code with a while(true) loop, or else make
use of an IL command called goto to physically move the execution
environment’s pointer back to the beginning of the loop.
I did investigate the possibility of referencing a generic Tail Optimised
Recursion Call from F# and exposing it via a compiled DLL to C#, but that
has its own performance issues that make it a waste of effort.
There’s another possibility I’ve seen discussed online, and that’s to add a
post-build event that directly manipulates the .NET Intermediate Language
that C# compiles to so that it makes retrospective use of the F# Tail
Optimization feature. That’s very clever, but sounds too much like hard
work to me. It would be a potential extra maintainance task too.
In the next section, I’ll look into a technique to simulate Tail Optimised
Recursion Calls in C#.
Trampolining
I’m not entirely sure where the term Trampolining came from, but it pre-
dates .NET. The earliest references I could find were academic papers from
the 90s, looking at implementing some of the feaures of LiSP in C. I’d guess
it’s a little older even than that, though.
The basic idea is that you have a function that takes a thunk as a parameter -
a thunk being a block of code stored in a variable. In C# these are
implemented as Func or Action.
Having got the thunk, you create an indefinite loop with while(true)
and some way of assessing a condition that determines whether the loop
should terminate. This might be done with an additional Func that returns a
bool or else some sort of wrapper object that needs to be updated with
each iteration by the thunk.
But at the end of the day, what we’re looking at is basically hiding a while
loop at the back of our codebase. It’s true that while isn’t purely
functional, but this is one of those places where we might need to
compromise.
Fundamentally, C# is a hybrid language, supporting both OO and FP
paradigms. There are always going to be places where it’s not going to be
possible to have it behave in exactly the way F# does. This is one of them.
There are a number of ways that you could implement trampolining, but this
is the one I’d tend to go for:
public static class FunctionalExtensions
{
public static T IterateUntil<T>(this T @this, Func<T, T>
updateFunction, Func<T, bool> endCondition)
{
var currentThis = @this;
while(!endCondition(currentThis))
{
currentThis = updateFunction(currentThis);
}
return currentThis;
}
}
By attaching to type T - a generic - this attaches to everything. The first
parameter is a Func delegate that updates the type that T represents to a
new form based on whatever rules the outside world defines. The second is
another Func which returns the condition that will cause the loop to
terminate.
Since this is a simple While loop, there aren’t any issues with the size of
the stack. It’s not pure functional programming, though. It’s a compromise.
At the very least though, it’s at least a single instance of a while loop
that’s hidden somewhere, deep in the codebase. It may also be that one day,
Microsoft will release a new feature that enables proper tail optimized
recursion calls to be implemented somehow, in which case this function can
be re-implemented and the code should continue to work as it did, but with
one instance fewer of imperative code features.
using this version of indefinite iteration, the Monopoly code would now look
like this:
// we need everything required to both update and
// assess whether we should continue or not in a
// single object, so I'm considering it "state" rather than
// simply inventory
var playerState = geState();
var rnd = getRandomNumberGenerator();
var playerState.IterateUntil(x => {
var action = GetAction();
return action switch
{
Actions.PayFine => x with
{
Money = x.Money - 50,
LastAction = action
},
Actions.GetOutOfJailFree => x with
{
GetOutOfJail = x.GetOutOfJail - 1,
LastAction = action
},
_ => x with
{
DieOne = rnd.Random(1, 6),
DieTwo = rnd.Random(1, 6)
}
}
},
x => x.LastAction == Actions.PayFine ||
x.LastAction == Actions.GetOutOfJailFree ||
x.DieOne == x.DieTwo
);
There is a third option, which you could consider which requires quite a bit
more boilerplate, but which ultimately looks a little friendlier than the
previous two versions.
Have a look, and see what you think.
Custom Iterator
The third option is to hack around with IEnumerables and
IEnumerators. The thing about IEnumerables is they aren’t actually
arrays, they’re just pointers to an item of data, and an instruction on how to
get the next item. That being the case, we can create our own implementation
of the IEnumerable interface, but with our own behavior.
In the case of our Monopoly example, we want an IEnumerable that’s
going to iterate until the user has selected a method to get out of jail, or else
rolled a double.
We actually start in the outside world with an IEnumerable, but the
IEnumerable only has a single function that has to be impemented:
GetEnumerator(). The IEnumerator is the class that sits behind the
scenes and actually does the work of enumerating. That’s what we need to
start with.
Anatomy of an Enumerator
This is what the IEnumerator Interface effectively looks like
(there’s some inheritance involved, so this isn’t all actually contained in
a single Interface):
public interface IEnumerator<T>
{
object Current { get; }
object IEnumerator.Current { get; }
void Dispose();
bool MoveNext();
void Reset();
}
Each of these functions has a very specific job to do:
Current / IEnumerator.Current - Get the current item. If iteration hasn’t
begun, this typically returns NULL.
Dispose - IEnumerator implements IDisposable
MoveNext - Move from the current item to the next. The bool return
value indicates whether another item was found. If there are no more
items to iterate over, false is returned.
Reset - move back to the beginning of the set of iteratable items.
Most of the time, an Enumerator is simply enumerating over an array,
in which case I’d imagine the implementation probably works something
like this:
public class ArrayEnumerable<T> : IEnumerator<T>
{
public readonly T[] _data;
public int pos = -1;
public ArrayEnumerable(T[] data)
{
this._data = data;
}
T Current => pos == -1 ? _data[pos] : null;
public void Dispose()
{
this._data = null;
}
public bool MoveNext()
{
this.pos = this.pos + 1;
return this.pos < this._data.Length;
}
public void Reset()
{
this.pos = -1;
}
}
I expect the real code is likely far more complicated than that, but this simple
implementation gives you an idea of what sort of a job it is that the
Enumerator does.
Implementing Custom Enumerators
Knowing how it works under the surface, you can see how it’s possible to
implement any behavior whatsoever that you’d like in an Enumerable. If
you wanted to, you could do madness like an Enumerable that only
iterates through every other item in an array by providing an alternative
implementation of MoveNext like this:
public bool MoveNext()
{
this.pos = this.pos == -1 ? this._data.Length - 1
this.pos = this.pos + 2;
return this.pos < this._data.Length;
}
// This turns { 1, 2, 3, 4 }
into { 2, 4 }
How about an Enumerator that loops over ever item twice, effectively
creating a duplicate of each item when enumerating:
public bool IsCopy = false;
public bool MoveNext()
{
if(this.IsCopy)
{
this.pos = this.pos + 1;
}
this.IsCopy = !this.IsCopy;
return this.pos < this._data.Length
}
// This turns { 1, 2, 3 }
// into { 1, 1, 2, 2, 3, 3 }
Or an entire implementation that goes backwards, starting with an
Enumerator outer wrapper:
public class BackwardsEnumerator<T> : IEnumerable<T>
{
private readonly T[] data;
public BackwardsEnumerator(IEnumerable<T> data)
{
this.data = data.ToArray();
}
public IEnumerator<T> GetEnumerator()
{
return new BackwardsArrayEnumerable<T>(this.data);
}
IEnumerator IEnumerable.GetEnumerator() =>
GetEnumerator();
}
And aftwards the actual Enumerator that drives the backwards motion:
public class BackwardsArrayEnumerable<T> : IEnumerator<T>
{
public readonly T[] _data;
public int pos;
public BackwardsArrayEnumerable(T[] data)
{
this._data = data ?? new T[0];
this.pos = this._data.Length;
}
T Current => (this._data != null && this._data.Length > 0
&&
this.pos >= 0 && this.pos < this._data.Length)
? _data[pos] : default;
object IEnumerator.Current => this.Current;
T IEnumerator<T>.Current => this.Current;
public void Dispose()
{
// Nothing to dispose
}
public bool MoveNext()
{
this.pos = this.pos - 1;
return this.pos >= 0;
}
public void Reset()
{
this.pos = this._data.Length;
}
}
The usage of this backwards enumerable is pretty much exactly the same as a
normal enumerable:
var data = new[] { 1, 2, 3, 4, 5, 6, 7, 8 };
var backwardsEnumerator = new BackwardsEnumerator<int>
(data);
var list = new List<int>();
foreach(var d in backwardsEnumerator)
{
list.Add(d);
}
// list = { 8, 7, 6, 5, 4, 3, 2, 1 }
So, now that you’ve seen how easy it is to create your own Enumerable
with whatever custom behavior you want, it should be easy enough to conjure
up an Enumerable that iterates indefinitely.
Indefinitely Looping Enumerables
Try saying this section title ten times fast!
As you saw in the previous section though, there’s no special reason that an
Enumerable has to start at the beginning and loop to the end. We can
make it behave in absolutely any way we care to.
What I want to do in this case, is - instead of an array - I want to pass in a
single state object of some kind, along with a bundle of code (i.e. a Thunk, or
Func delegate) for determining whether the loop should continue or not.
Working backwards, the first thing I’ll make is the Enumerator. This is an
entirely bespoke enumeration process, so I’m not going to make any effort to
make it generic in any way. The logic I’m writing wouldn’t make sense
outside of a game state object.
I might want to do several different iterations in my hypothetical Monopoly
implementation though, so I’ll make the operation and loop termination logic
somewhat generic.
public class GameEnumerator : IEnumerator<Game>
{
// I need this in case of a restart
private Game StartState;
private Game CurrentState;
// old game state -> new game state
private readonly Func<Game, Game> iterator;
// Should the iteration stop?
private Func<Game, bool> endCondition;
// some tricky logic required to ensure the final
// game state is iterated. Normal logic is that if
// the MoveNext function returns false, then there isn't
// anything pulled from Current, the loop simply
terminates
private bool stopIterating = false;
public GameEnumerator(Game state, Func<Game, Game>
iterator,
Func<Game, bool> endCondition)
{
this.StartState = state;
this.CurrentState = state;
this.iterator = iterator;
this.endCondition = endCondition;
}
public Game Current => this.CurrentState;
object IEnumerator.Current => Current;
public void Dispose()
{
// Nothing to dispose
}
public bool MoveNext()
{
var newState = this.iterator(this.CurrentState);
// Not strictly functional here, but as always with
// this topic, a compromise is needed
this.CurrentState = newState;
// Have we completed the final iteration?
That's done
after
// reaching the end condition
if (stopIterating)
return false;
var endConditionMet =
this.endCondition(this.CurrentState);
var lastIteration = !this.stopIterating &&
endConditionMet;
this.stopIterating = endConditionMet;
return !this.stopIterating || lastIteration;
}
public void Reset()
{
// restore the initial state
this.CurrentState = this.StartState;
}
}
That’s the hard bit done!! We have an engine under the surface that’ll allow
us to iterate through successive states until we’re finished - whatever we
decide “finished” means.
Next item required is the IEnumerable to run the Enumerator. That’s
pretty straightforward:
public class GameIterator : IEnumerable<Game>
{
private readonly Game _startState;
private readonly Func<Game,Game> _iterator;
private readonly Func<Game,bool> _endCondition;
public GameIterator(Game startState, Func<Game, Game>
iterator,
Func<Game, bool> endCondition)
{
this._startState = startState;
this._iterator = iterator;
this._endCondition = endCondition;
}
public IEnumerator<Game> GetEnumerator() =>
new GameEnumerator(this._startState, this._iterator,
this._endCondition);
}
IEnumerator IEnumerable.GetEnumerator() =>
GetEnumerator();
}
Everything is now in place to carry out a custom iteration. I just need to
define my custom logic, set up the iterator.
var playerState = geState();
var rnd = getRandomNumberGenerator();
var endCondition = (Game x) => x.x.LastAction ==
Actions.PayFine ||
x.LastAction == Actions.GetOutOfJailFree ||
x.DieOne == x.DieTwo);
var update = (Game x) => {
var action = GetAction();
return action switch
{
Actions.PayFine => x with
{
Money = x.Money - 50,
LastAction = action
},
Actions.GetOutOfJailFree => x with
{
GetOutOfJail = x.GetOutOfJail - 1,
LastAction = action
},
_ => x with
{
DieOne = rnd.Random(1, 6),
DieTwo = rnd.Random(1, 6)
}
}
}
var gameIterator = new GameIterator(playerState, update,
endCondition);
There are a couple of options for how to handle the iteration itself, and I’d
like to take a little time out to discuss each of those options in a little
more detail.
Using Indefinite Iterators
Strictly speaking, as a fully-fledged Iterator any LINQ operation can be
applied, as well as a standard ForEach iteration.
ForEach would probably be the simplest way to handle this iteration, but
it wouldn’t be strictly functional. It’s up to you, if you want to compromise.
It might look like this:
foreach(var g in gameIterator)
{
// store the updated state outside of the loop.
playerState = g;
// Here you can do whatever logic you'd like to do
// to message back to the player.
Write a message onto
screen
// or whatever is useful for them to be prompted to do
another action
}
// At the end of the loop here, the player is now out of
jail, and
// the game can continue with the updatd version of
playerState;
That wouldn’t give me too many causes for concern in production code,
honestly. But, what we’ve done is negated all of the work we’ve put
into attempting to get rid of non-functional code from our codebase.
The other options involve the use of LINQ. As a fully-fledged
Enumerable, our GameIterator can have any LINQ operations applied to
it. Which ones would be the best, though?
Select would be an obvious starting place, but it might not entirely
behave as you’d expect. Usage is pretty much the same as any normal
Select list operation you’ve ever done before:
var gameStates = gameIterator.Select(x => x);
The trick here is that we’re treating gameIterator as an array, so Select -
ing from it will result in an array of game states. What you’ll basically have
is an array of every intermedate step the user has gone through, finishing with
the final state in the last element.
The easy way to reduce this down to simply the final state is to substitute
Select for Last:
var endState = var gameStates = gameIterator.Last();
This assumes, of course that you aren’t interested in the intermediate steps. It
might be that you want to compose a message to the user for each state
update, in which case you might want to select, and provide a transformation.
Something like this, perhaps:
var messages = gameIterator.Select(x =>
"You chose to do " + x.LastAction + " and are " +
(x.InJail ? "In Jail" : "Free to go!");
);
That eradicates the actual game state, though, so possibly Aggregate
might be a better option:
var stateAndMessages = (
Messages: Enumerable.Empty<string>(),
State: playerState
);
var updatedStateAndMessages =
stateAndMessages.Aggregate(stateAndMessages, (acc, x) => (
acc.Messages.Append("You chose to do " + x.LastAction + "
and are " +
(x.InJail ? "In Jail" : "Free to go!")),
x
));
The x in each iteration of the Aggregate process is an updated version of
the Game State, and it’ll carry on aggregating until the declared end
condition is met. Each pass appends a message to the list, so what you finally
get at the end is a Tuple containing an array of strings, which are messages
to pass to the player, and the final version of the game state.
Bear in mind that any use of LINQ statements that will terminate the iteration
early in some manner - First, Take, etc. will also premeturely end this
iteration proces, possibly in our instance with the player still in jail.
Of course, this might be a behavior you actually want! Maybe you’re
restricting the player to just a couple of actions before moving onto another
part of the game, or another player’s turn. Something like that.
There are all sorts of possibilities for the logic you could come up with,
playing with this technique.
As you saw in the previous section though, there’s no special reason that an
Enumerable has to start at the beginning and loop to the end. We can
make it behave in absolutely any way we care to.
What I want to do in this case, is - instead of an array - I want to pass in a
single state object of some kind, along with a bundle of code (i.e. a Thunk, or
Func delegate) for determining whether the loop should continue or not.
Working backwards, the first thing I’ll make is the Enumerator. This is an
entirely bespoke enumeration process, so I’m not going to make any effort to
make it generic in any way. The logic I’m writing wouldn’t make sense
outside of a game state object.
I might want to do several different iterations in my hypothetical Monopoly
implementation though, so I’ll make the operation and loop termination logic
somewhat generic.
public class GameEnumerator : IEnumerator<Game>
{
// I need this in case of a restart
private Game StartState;
private Game CurrentState;
// old game state -> new game state
private readonly Func<Game, Game> iterator;
// Should the iteration stop?
private Func<Game, bool> endCondition;
// some tricky logic required to ensure the final
// game state is iterated. Normal logic is that if
// the MoveNext function returns false, then there isn't
// anything pulled from Current, the loop simply
terminates
private bool stopIterating = false;
public GameEnumerator(Game state, Func<Game, Game>
iterator,
Func<Game, bool> endCondition)
{
this.StartState = state;
this.CurrentState = state;
this.iterator = iterator;
this.endCondition = endCondition;
}
public Game Current => this.CurrentState;
object IEnumerator.Current => Current;
public void Dispose()
{
// Nothing to dispose
}
public bool MoveNext()
{
var newState = this.iterator(this.CurrentState);
// Not strictly functional here, but as always with
// this topic, a compromise is needed
this.CurrentState = newState;
// Have we completed the final iteration?
That's done
after
// reaching the end condition
if (stopIterating)
return false;
var endConditionMet =
this.endCondition(this.CurrentState);
var lastIteration = !this.stopIterating &&
endConditionMet;
this.stopIterating = endConditionMet;
return !this.stopIterating || lastIteration;
}
public void Reset()
{
// restore the initial state
this.CurrentState = this.StartState;
}
}
That’s the hard bit done!! We have an engine under the surface that’ll allow
us to iterate through successive states until we’re finished - whatever we
decide “finished” means.
Next item required is the IEnumerable to run the Enumerator. That’s
pretty straightforward:
public class GameIterator : IEnumerable<Game>
{
private readonly Game _startState;
private readonly Func<Game,Game> _iterator;
private readonly Func<Game,bool> _endCondition;
public GameIterator(Game startState, Func<Game, Game>
iterator,
Func<Game, bool> endCondition)
{
this._startState = startState;
this._iterator = iterator;
this._endCondition = endCondition;
}
public IEnumerator<Game> GetEnumerator() =>
new GameEnumerator(this._startState, this._iterator,
this._endCondition);
}
IEnumerator IEnumerable.GetEnumerator() =>
GetEnumerator();
}
Everything is now in place to carry out a custom iteration. I just need to
define my custom logic, set up the iterator.
var playerState = geState();
var rnd = getRandomNumberGenerator();
var endCondition = (Game x) => x.x.LastAction ==
Actions.PayFine ||
x.LastAction == Actions.GetOutOfJailFree ||
x.DieOne == x.DieTwo);
var update = (Game x) => {
var action = GetAction();
return action switch
{
Actions.PayFine => x with
{
Money = x.Money - 50,
LastAction = action
},
Actions.GetOutOfJailFree => x with
{
GetOutOfJail = x.GetOutOfJail - 1,
LastAction = action
},
_ => x with
{
DieOne = rnd.Random(1, 6),
DieTwo = rnd.Random(1, 6)
}
}
}
var gameIterator = new GameIterator(playerState, update,
endCondition);
There are a couple of options for how to handle the iteration itself, and I’d
like to take a little time out to discuss each of those options in a little
more detail.
Using Indefinite Iterators
Strictly speaking, as a fully-fledged Iterator any LINQ operation can be
applied, as well as a standard ForEach iteration.
ForEach would probably be the simplest way to handle this iteration, but
it wouldn’t be strictly functional. It’s up to you, if you want to compromise.
It might look like this:
foreach(var g in gameIterator)
{
// store the updated state outside of the loop.
playerState = g;
// Here you can do whatever logic you'd like to do
// to message back to the player.
Write a message onto
screen
// or whatever is useful for them to be prompted to do
another action
}
// At the end of the loop here, the player is now out of
jail, and
// the game can continue with the updatd version of
playerState;
That wouldn’t give me too many causes for concern in production code,
honestly. But, what we’ve done is negated all of the work we’ve put
into attempting to get rid of non-functional code from our codebase.
The other options involve the use of LINQ. As a fully-fledged
Enumerable, our GameIterator can have any LINQ operations applied to
it. Which ones would be the best, though?
Select would be an obvious starting place, but it might not entirely
behave as you’d expect. Usage is pretty much the same as any normal
Select list operation you’ve ever done before:
var gameStates = gameIterator.Select(x => x);
The trick here is that we’re treating gameIterator as an array, so Select -
ing from it will result in an array of game states. What you’ll basically have
is an array of every intermedate step the user has gone through, finishing with
the final state in the last element.
The easy way to reduce this down to simply the final state is to substitute
Select for Last:
var endState = var gameStates = gameIterator.Last();
This assumes, of course that you aren’t interested in the intermediate steps. It
might be that you want to compose a message to the user for each state
update, in which case you might want to select, and provide a transformation.
Something like this, perhaps:
var messages = gameIterator.Select(x =>
"You chose to do " + x.LastAction + " and are " +
(x.InJail ? "In Jail" : "Free to go!");
);
That eradicates the actual game state, though, so possibly Aggregate
might be a better option:
var stateAndMessages = (
Messages: Enumerable.Empty<string>(),
State: playerState
);
var updatedStateAndMessages =
stateAndMessages.Aggregate(stateAndMessages, (acc, x) => (
acc.Messages.Append("You chose to do " + x.LastAction + "
and are " +
(x.InJail ? "In Jail" : "Free to go!")),
x
));
As you saw in the previous section though, there’s no special reason that an
Enumerable has to start at the beginning and loop to the end. We can
make it behave in absolutely any way we care to.
What I want to do in this case, is - instead of an array - I want to pass in a
single state object of some kind, along with a bundle of code (i.e. a Thunk, or
Func delegate) for determining whether the loop should continue or not.
Working backwards, the first thing I’ll make is the Enumerator. This is an
entirely bespoke enumeration process, so I’m not going to make any effort to
make it generic in any way. The logic I’m writing wouldn’t make sense
outside of a game state object.
I might want to do several different iterations in my hypothetical Monopoly
implementation though, so I’ll make the operation and loop termination logic
somewhat generic.
public class GameEnumerator : IEnumerator<Game>
{
// I need this in case of a restart
private Game StartState;
private Game CurrentState;
// old game state -> new game state
private readonly Func<Game, Game> iterator;
// Should the iteration stop?
private Func<Game, bool> endCondition;
// some tricky logic required to ensure the final
// game state is iterated. Normal logic is that if
// the MoveNext function returns false, then there isn't
// anything pulled from Current, the loop simply
terminates
private bool stopIterating = false;
public GameEnumerator(Game state, Func<Game, Game>
iterator,
Func<Game, bool> endCondition)
{
this.StartState = state;
this.CurrentState = state;
this.iterator = iterator;
this.endCondition = endCondition;
}
public Game Current => this.CurrentState;
object IEnumerator.Current => Current;
public void Dispose()
{
// Nothing to dispose
}
public bool MoveNext()
{
var newState = this.iterator(this.CurrentState);
// Not strictly functional here, but as always with
// this topic, a compromise is needed
this.CurrentState = newState;
// Have we completed the final iteration?
That's done
after
// reaching the end condition
if (stopIterating)
return false;
var endConditionMet =
this.endCondition(this.CurrentState);
var lastIteration = !this.stopIterating &&
endConditionMet;
this.stopIterating = endConditionMet;
return !this.stopIterating || lastIteration;
}
public void Reset()
{
// restore the initial state
this.CurrentState = this.StartState;
}
}
That’s the hard bit done!! We have an engine under the surface that’ll allow
us to iterate through successive states until we’re finished - whatever we
decide “finished” means.
Next item required is the IEnumerable to run the Enumerator. That’s
pretty straightforward:
public class GameIterator : IEnumerable<Game>
{
private readonly Game _startState;
private readonly Func<Game,Game> _iterator;
private readonly Func<Game,bool> _endCondition;
public GameIterator(Game startState, Func<Game, Game>
iterator,
Func<Game, bool> endCondition)
{
this._startState = startState;
this._iterator = iterator;
this._endCondition = endCondition;
}
public IEnumerator<Game> GetEnumerator() =>
new GameEnumerator(this._startState, this._iterator,
this._endCondition);
}
IEnumerator IEnumerable.GetEnumerator() =>
GetEnumerator();
}
Everything is now in place to carry out a custom iteration. I just need to
define my custom logic, set up the iterator.
var playerState = geState();
var rnd = getRandomNumberGenerator();
var endCondition = (Game x) => x.x.LastAction ==
Actions.PayFine ||
x.LastAction == Actions.GetOutOfJailFree ||
x.DieOne == x.DieTwo);
var update = (Game x) => {
var action = GetAction();
return action switch
{
Actions.PayFine => x with
{
Money = x.Money - 50,
LastAction = action
},
Actions.GetOutOfJailFree => x with
{
GetOutOfJail = x.GetOutOfJail - 1,
LastAction = action
},
_ => x with
{
DieOne = rnd.Random(1, 6),
DieTwo = rnd.Random(1, 6)
}
}
}
var gameIterator = new GameIterator(playerState, update,
endCondition);
There are a couple of options for how to handle the iteration itself, and I’d
like to take a little time out to discuss each of those options in a little
more detail.
Using Indefinite Iterators
Strictly speaking, as a fully-fledged Iterator any LINQ operation can be
applied, as well as a standard ForEach iteration.
ForEach would probably be the simplest way to handle this iteration, but
it wouldn’t be strictly functional. It’s up to you, if you want to compromise.
It might look like this:
foreach(var g in gameIterator)
{
// store the updated state outside of the loop.
playerState = g;
// Here you can do whatever logic you'd like to do
// to message back to the player.
Write a message onto
screen
// or whatever is useful for them to be prompted to do
another action
}
// At the end of the loop here, the player is now out of
jail, and
// the game can continue with the updatd version of
playerState;
That wouldn’t give me too many causes for concern in production code,
honestly. But, what we’ve done is negated all of the work we’ve put
into attempting to get rid of non-functional code from our codebase.
The other options involve the use of LINQ. As a fully-fledged
Enumerable, our GameIterator can have any LINQ operations applied to
it. Which ones would be the best, though?
Select would be an obvious starting place, but it might not entirely
behave as you’d expect. Usage is pretty much the same as any normal
Select list operation you’ve ever done before:
var gameStates = gameIterator.Select(x => x);
The trick here is that we’re treating gameIterator as an array, so Select -
ing from it will result in an array of game states. What you’ll basically have
is an array of every intermedate step the user has gone through, finishing with
the final state in the last element.
The easy way to reduce this down to simply the final state is to substitute
Select for Last:
var endState = var gameStates = gameIterator.Last();
This assumes, of course that you aren’t interested in the intermediate steps. It
might be that you want to compose a message to the user for each state
update, in which case you might want to select, and provide a transformation.
Something like this, perhaps:
var messages = gameIterator.Select(x =>
"You chose to do " + x.LastAction + " and are " +
(x.InJail ? "In Jail" : "Free to go!");
);
That eradicates the actual game state, though, so possibly Aggregate
might be a better option:
var stateAndMessages = (
Messages: Enumerable.Empty<string>(),
State: playerState
);
var updatedStateAndMessages =
stateAndMessages.Aggregate(stateAndMessages, (acc, x) => (
acc.Messages.Append("You chose to do " + x.LastAction + "
and are " +
(x.InJail ? "In Jail" : "Free to go!")),
x
));
As you saw in the previous section though, there’s no special reason that an
Enumerable has to start at the beginning and loop to the end. We can
make it behave in absolutely any way we care to.
What I want to do in this case, is - instead of an array - I want to pass in a
single state object of some kind, along with a bundle of code (i.e. a Thunk, or
Func delegate) for determining whether the loop should continue or not.
Working backwards, the first thing I’ll make is the Enumerator. This is an
entirely bespoke enumeration process, so I’m not going to make any effort to
make it generic in any way. The logic I’m writing wouldn’t make sense
outside of a game state object.
I might want to do several different iterations in my hypothetical Monopoly
implementation though, so I’ll make the operation and loop termination logic
somewhat generic.
public class GameEnumerator : IEnumerator<Game>
{
// I need this in case of a restart
private Game StartState;
private Game CurrentState;
// old game state -> new game state
private readonly Func<Game, Game> iterator;
// Should the iteration stop?
private Func<Game, bool> endCondition;
// some tricky logic required to ensure the final
// game state is iterated. Normal logic is that if
// the MoveNext function returns false, then there isn't
// anything pulled from Current, the loop simply
terminates
private bool stopIterating = false;
public GameEnumerator(Game state, Func<Game, Game>
iterator,
Func<Game, bool> endCondition)
{
this.StartState = state;
this.CurrentState = state;
this.iterator = iterator;
this.endCondition = endCondition;
}
public Game Current => this.CurrentState;
object IEnumerator.Current => Current;
public void Dispose()
{
// Nothing to dispose
}
public bool MoveNext()
{
var newState = this.iterator(this.CurrentState);
// Not strictly functional here, but as always with
// this topic, a compromise is needed
this.CurrentState = newState;
// Have we completed the final iteration?
That's done
after
// reaching the end condition
if (stopIterating)
return false;
var endConditionMet =
this.endCondition(this.CurrentState);
var lastIteration = !this.stopIterating &&
endConditionMet;
this.stopIterating = endConditionMet;
return !this.stopIterating || lastIteration;
}
public void Reset()
{
// restore the initial state
this.CurrentState = this.StartState;
}
}
That’s the hard bit done!! We have an engine under the surface that’ll allow
us to iterate through successive states until we’re finished - whatever we
decide “finished” means.
Next item required is the IEnumerable to run the Enumerator. That’s
pretty straightforward:
public class GameIterator : IEnumerable<Game>
{
private readonly Game _startState;
private readonly Func<Game,Game> _iterator;
private readonly Func<Game,bool> _endCondition;
public GameIterator(Game startState, Func<Game, Game>
iterator,
Func<Game, bool> endCondition)
{
this._startState = startState;
this._iterator = iterator;
this._endCondition = endCondition;
}
public IEnumerator<Game> GetEnumerator() =>
new GameEnumerator(this._startState, this._iterator,
this._endCondition);
}
IEnumerator IEnumerable.GetEnumerator() =>
GetEnumerator();
}
Everything is now in place to carry out a custom iteration. I just need to
define my custom logic, set up the iterator.
var playerState = geState();
var rnd = getRandomNumberGenerator();
var endCondition = (Game x) => x.x.LastAction ==
Actions.PayFine ||
x.LastAction == Actions.GetOutOfJailFree ||
x.DieOne == x.DieTwo);
var update = (Game x) => {
var action = GetAction();
return action switch
{
Actions.PayFine => x with
{
Money = x.Money - 50,
LastAction = action
},
Actions.GetOutOfJailFree => x with
{
GetOutOfJail = x.GetOutOfJail - 1,
LastAction = action
},
_ => x with
{
DieOne = rnd.Random(1, 6),
DieTwo = rnd.Random(1, 6)
}
}
}
var gameIterator = new GameIterator(playerState, update,
endCondition);
There are a couple of options for how to handle the iteration itself, and I’d
like to take a little time out to discuss each of those options in a little
more detail.
Using Indefinite Iterators
Strictly speaking, as a fully-fledged Iterator any LINQ operation can be
applied, as well as a standard ForEach iteration.
ForEach would probably be the simplest way to handle this iteration, but
it wouldn’t be strictly functional. It’s up to you, if you want to compromise.
It might look like this:
foreach(var g in gameIterator)
{
// store the updated state outside of the loop.
playerState = g;
// Here you can do whatever logic you'd like to do
// to message back to the player.
Write a message onto
screen
// or whatever is useful for them to be prompted to do
another action
}
// At the end of the loop here, the player is now out of
jail, and
// the game can continue with the updatd version of
playerState;
That wouldn’t give me too many causes for concern in production code,
honestly. But, what we’ve done is negated all of the work we’ve put
into attempting to get rid of non-functional code from our codebase.
The other options involve the use of LINQ. As a fully-fledged
Enumerable, our GameIterator can have any LINQ operations applied to
it. Which ones would be the best, though?
Select would be an obvious starting place, but it might not entirely
behave as you’d expect. Usage is pretty much the same as any normal
Select list operation you’ve ever done before:
var gameStates = gameIterator.Select(x => x);
The trick here is that we’re treating gameIterator as an array, so Select -
ing from it will result in an array of game states. What you’ll basically have
is an array of every intermedate step the user has gone through, finishing with
the final state in the last element.
The easy way to reduce this down to simply the final state is to substitute
Select for Last:
var endState = var gameStates = gameIterator.Last();
This assumes, of course that you aren’t interested in the intermediate steps. It
might be that you want to compose a message to the user for each state
update, in which case you might want to select, and provide a transformation.
Something like this, perhaps:
var messages = gameIterator.Select(x =>
"You chose to do " + x.LastAction + " and are " +
(x.InJail ? "In Jail" : "Free to go!");
);
That eradicates the actual game state, though, so possibly Aggregate
might be a better option:
var stateAndMessages = (
Messages: Enumerable.Empty<string>(),
State: playerState
);
var updatedStateAndMessages =
stateAndMessages.Aggregate(stateAndMessages, (acc, x) => (
acc.Messages.Append("You chose to do " + x.LastAction + "
and are " +
(x.InJail ? "In Jail" : "Free to go!")),
x
));
As you saw in the previous section though, there’s no special reason that an
Enumerable has to start at the beginning and loop to the end. We can
make it behave in absolutely any way we care to.
What I want to do in this case, is - instead of an array - I want to pass in a
single state object of some kind, along with a bundle of code (i.e. a Thunk, or
Func delegate) for determining whether the loop should continue or not.
Working backwards, the first thing I’ll make is the Enumerator. This is an
entirely bespoke enumeration process, so I’m not going to make any effort to
make it generic in any way. The logic I’m writing wouldn’t make sense
outside of a game state object.
I might want to do several different iterations in my hypothetical Monopoly
implementation though, so I’ll make the operation and loop termination logic
somewhat generic.
public class GameEnumerator : IEnumerator<Game>
{
// I need this in case of a restart
private Game StartState;
private Game CurrentState;
// old game state -> new game state
private readonly Func<Game, Game> iterator;
// Should the iteration stop?
private Func<Game, bool> endCondition;
// some tricky logic required to ensure the final
// game state is iterated. Normal logic is that if
// the MoveNext function returns false, then there isn't
// anything pulled from Current, the loop simply
terminates
private bool stopIterating = false;
public GameEnumerator(Game state, Func<Game, Game>
iterator,
Func<Game, bool> endCondition)
{
this.StartState = state;
this.CurrentState = state;
this.iterator = iterator;
this.endCondition = endCondition;
}
public Game Current => this.CurrentState;
object IEnumerator.Current => Current;
public void Dispose()
{
// Nothing to dispose
}
public bool MoveNext()
{
var newState = this.iterator(this.CurrentState);
// Not strictly functional here, but as always with
// this topic, a compromise is needed
this.CurrentState = newState;
// Have we completed the final iteration?
That's done
after
// reaching the end condition
if (stopIterating)
return false;
var endConditionMet =
this.endCondition(this.CurrentState);
var lastIteration = !this.stopIterating &&
endConditionMet;
this.stopIterating = endConditionMet;
return !this.stopIterating || lastIteration;
}
public void Reset()
{
// restore the initial state
this.CurrentState = this.StartState;
}
}
That’s the hard bit done!! We have an engine under the surface that’ll allow
us to iterate through successive states until we’re finished - whatever we
decide “finished” means.
Next item required is the IEnumerable to run the Enumerator. That’s
pretty straightforward:
public class GameIterator : IEnumerable<Game>
{
private readonly Game _startState;
private readonly Func<Game,Game> _iterator;
private readonly Func<Game,bool> _endCondition;
public GameIterator(Game startState, Func<Game, Game>
iterator,
Func<Game, bool> endCondition)
{
this._startState = startState;
this._iterator = iterator;
this._endCondition = endCondition;
}
public IEnumerator<Game> GetEnumerator() =>
new GameEnumerator(this._startState, this._iterator,
this._endCondition);
}
IEnumerator IEnumerable.GetEnumerator() =>
GetEnumerator();
}
Everything is now in place to carry out a custom iteration. I just need to
define my custom logic, set up the iterator.
var playerState = geState();
var rnd = getRandomNumberGenerator();
var endCondition = (Game x) => x.x.LastAction ==
Actions.PayFine ||
x.LastAction == Actions.GetOutOfJailFree ||
x.DieOne == x.DieTwo);
var update = (Game x) => {
var action = GetAction();
return action switch
{
Actions.PayFine => x with
{
Money = x.Money - 50,
LastAction = action
},
Actions.GetOutOfJailFree => x with
{
GetOutOfJail = x.GetOutOfJail - 1,
LastAction = action
},
_ => x with
{
DieOne = rnd.Random(1, 6),
DieTwo = rnd.Random(1, 6)
}
}
}
var gameIterator = new GameIterator(playerState, update,
endCondition);
There are a couple of options for how to handle the iteration itself, and I’d
like to take a little time out to discuss each of those options in a little
more detail.
Using Indefinite Iterators
Strictly speaking, as a fully-fledged Iterator any LINQ operation can be
applied, as well as a standard ForEach iteration.
ForEach would probably be the simplest way to handle this iteration, but
it wouldn’t be strictly functional. It’s up to you, if you want to compromise.
It might look like this:
foreach(var g in gameIterator)
{
// store the updated state outside of the loop.
playerState = g;
// Here you can do whatever logic you'd like to do
// to message back to the player.
Write a message onto
screen
// or whatever is useful for them to be prompted to do
another action
}
// At the end of the loop here, the player is now out of
jail, and
// the game can continue with the updatd version of
playerState;
That wouldn’t give me too many causes for concern in production code,
honestly. But, what we’ve done is negated all of the work we’ve put
into attempting to get rid of non-functional code from our codebase.
The other options involve the use of LINQ. As a fully-fledged
Enumerable, our GameIterator can have any LINQ operations applied to
it. Which ones would be the best, though?
Select would be an obvious starting place, but it might not entirely
behave as you’d expect. Usage is pretty much the same as any normal
Select list operation you’ve ever done before:
var gameStates = gameIterator.Select(x => x);
The trick here is that we’re treating gameIterator as an array, so Select -
ing from it will result in an array of game states. What you’ll basically have
is an array of every intermedate step the user has gone through, finishing with
the final state in the last element.
The easy way to reduce this down to simply the final state is to substitute
Select for Last:
var endState = var gameStates = gameIterator.Last();
This assumes, of course that you aren’t interested in the intermediate steps. It
might be that you want to compose a message to the user for each state
update, in which case you might want to select, and provide a transformation.
Something like this, perhaps:
var messages = gameIterator.Select(x =>
"You chose to do " + x.LastAction + " and are " +
(x.InJail ? "In Jail" : "Free to go!");
);
That eradicates the actual game state, though, so possibly Aggregate
might be a better option:
var stateAndMessages = (
Messages: Enumerable.Empty<string>(),
State: playerState
);
var updatedStateAndMessages =
stateAndMessages.Aggregate(stateAndMessages, (acc, x) => (
acc.Messages.Append("You chose to do " + x.LastAction + "
and are " +
(x.InJail ? "In Jail" : "Free to go!")),
x
));
As you saw in the previous section though, there’s no special reason that an
Enumerable has to start at the beginning and loop to the end. We can
make it behave in absolutely any way we care to.
What I want to do in this case, is - instead of an array - I want to pass in a
single state object of some kind, along with a bundle of code (i.e. a Thunk, or
Func delegate) for determining whether the loop should continue or not.
Working backwards, the first thing I’ll make is the Enumerator. This is an
entirely bespoke enumeration process, so I’m not going to make any effort to
make it generic in any way. The logic I’m writing wouldn’t make sense
outside of a game state object.
I might want to do several different iterations in my hypothetical Monopoly
implementation though, so I’ll make the operation and loop termination logic
somewhat generic.
public class GameEnumerator : IEnumerator<Game>
{
// I need this in case of a restart
private Game StartState;
private Game CurrentState;
// old game state -> new game state
private readonly Func<Game, Game> iterator;
// Should the iteration stop?
private Func<Game, bool> endCondition;
// some tricky logic required to ensure the final
// game state is iterated. Normal logic is that if
// the MoveNext function returns false, then there isn't
// anything pulled from Current, the loop simply
terminates
private bool stopIterating = false;
public GameEnumerator(Game state, Func<Game, Game>
iterator,
Func<Game, bool> endCondition)
{
this.StartState = state;
this.CurrentState = state;
this.iterator = iterator;
this.endCondition = endCondition;
}
public Game Current => this.CurrentState;
object IEnumerator.Current => Current;
public void Dispose()
{
// Nothing to dispose
}
public bool MoveNext()
{
var newState = this.iterator(this.CurrentState);
// Not strictly functional here, but as always with
// this topic, a compromise is needed
this.CurrentState = newState;
// Have we completed the final iteration?
That's done
after
// reaching the end condition
if (stopIterating)
return false;
var endConditionMet =
this.endCondition(this.CurrentState);
var lastIteration = !this.stopIterating &&
endConditionMet;
this.stopIterating = endConditionMet;
return !this.stopIterating || lastIteration;
}
public void Reset()
{
// restore the initial state
this.CurrentState = this.StartState;
}
}
That’s the hard bit done!! We have an engine under the surface that’ll allow
us to iterate through successive states until we’re finished - whatever we
decide “finished” means.
Next item required is the IEnumerable to run the Enumerator. That’s
pretty straightforward:
public class GameIterator : IEnumerable<Game>
{
private readonly Game _startState;
private readonly Func<Game,Game> _iterator;
private readonly Func<Game,bool> _endCondition;
public GameIterator(Game startState, Func<Game, Game>
iterator,
Func<Game, bool> endCondition)
{
this._startState = startState;
this._iterator = iterator;
this._endCondition = endCondition;
}
public IEnumerator<Game> GetEnumerator() =>
new GameEnumerator(this._startState, this._iterator,
this._endCondition);
}
IEnumerator IEnumerable.GetEnumerator() =>
GetEnumerator();
}
Everything is now in place to carry out a custom iteration. I just need to
define my custom logic, set up the iterator.
var playerState = geState();
var rnd = getRandomNumberGenerator();
var endCondition = (Game x) => x.x.LastAction ==
Actions.PayFine ||
x.LastAction == Actions.GetOutOfJailFree ||
x.DieOne == x.DieTwo);
var update = (Game x) => {
var action = GetAction();
return action switch
{
Actions.PayFine => x with
{
Money = x.Money - 50,
LastAction = action
},
Actions.GetOutOfJailFree => x with
{
GetOutOfJail = x.GetOutOfJail - 1,
LastAction = action
},
_ => x with
{
DieOne = rnd.Random(1, 6),
DieTwo = rnd.Random(1, 6)
}
}
}
var gameIterator = new GameIterator(playerState, update,
endCondition);
There are a couple of options for how to handle the iteration itself, and I’d
like to take a little time out to discuss each of those options in a little
more detail.
Using Indefinite Iterators
Strictly speaking, as a fully-fledged Iterator any LINQ operation can be
applied, as well as a standard ForEach iteration.
ForEach would probably be the simplest way to handle this iteration, but
it wouldn’t be strictly functional. It’s up to you, if you want to compromise.
It might look like this:
foreach(var g in gameIterator)
{
// store the updated state outside of the loop.
playerState = g;
// Here you can do whatever logic you'd like to do
// to message back to the player.
Write a message onto
screen
// or whatever is useful for them to be prompted to do
another action
}
// At the end of the loop here, the player is now out of
jail, and
// the game can continue with the updatd version of
playerState;
That wouldn’t give me too many causes for concern in production code,
honestly. But, what we’ve done is negated all of the work we’ve put
into attempting to get rid of non-functional code from our codebase.
The other options involve the use of LINQ. As a fully-fledged
Enumerable, our GameIterator can have any LINQ operations applied to
it. Which ones would be the best, though?
Select would be an obvious starting place, but it might not entirely
behave as you’d expect. Usage is pretty much the same as any normal
Select list operation you’ve ever done before:
var gameStates = gameIterator.Select(x => x);
The trick here is that we’re treating gameIterator as an array, so Select -
ing from it will result in an array of game states. What you’ll basically have
is an array of every intermedate step the user has gone through, finishing with
the final state in the last element.
The easy way to reduce this down to simply the final state is to substitute
Select for Last:
var endState = var gameStates = gameIterator.Last();
This assumes, of course that you aren’t interested in the intermediate steps. It
might be that you want to compose a message to the user for each state
update, in which case you might want to select, and provide a transformation.
Something like this, perhaps:
var messages = gameIterator.Select(x =>
"You chose to do " + x.LastAction + " and are " +
(x.InJail ? "In Jail" : "Free to go!");
);
That eradicates the actual game state, though, so possibly Aggregate
might be a better option:
var stateAndMessages = (
Messages: Enumerable.Empty<string>(),
State: playerState
);
var updatedStateAndMessages =
stateAndMessages.Aggregate(stateAndMessages, (acc, x) => (
acc.Messages.Append("You chose to do " + x.LastAction + "
and are " +
(x.InJail ? "In Jail" : "Free to go!")),
x
));
As you saw in the previous section though, there’s no special reason that an
Enumerable has to start at the beginning and loop to the end. We can
make it behave in absolutely any way we care to.
What I want to do in this case, is - instead of an array - I want to pass in a
single state object of some kind, along with a bundle of code (i.e. a Thunk, or
Func delegate) for determining whether the loop should continue or not.
Working backwards, the first thing I’ll make is the Enumerator. This is an
entirely bespoke enumeration process, so I’m not going to make any effort to
make it generic in any way. The logic I’m writing wouldn’t make sense
outside of a game state object.
I might want to do several different iterations in my hypothetical Monopoly
implementation though, so I’ll make the operation and loop termination logic
somewhat generic.
public class GameEnumerator : IEnumerator<Game>
{
// I need this in case of a restart
private Game StartState;
private Game CurrentState;
// old game state -> new game state
private readonly Func<Game, Game> iterator;
// Should the iteration stop?
private Func<Game, bool> endCondition;
// some tricky logic required to ensure the final
// game state is iterated. Normal logic is that if
// the MoveNext function returns false, then there isn't
// anything pulled from Current, the loop simply
terminates
private bool stopIterating = false;
public GameEnumerator(Game state, Func<Game, Game>
iterator,
Func<Game, bool> endCondition)
{
this.StartState = state;
this.CurrentState = state;
this.iterator = iterator;
this.endCondition = endCondition;
}
public Game Current => this.CurrentState;
object IEnumerator.Current => Current;
public void Dispose()
{
// Nothing to dispose
}
public bool MoveNext()
{
var newState = this.iterator(this.CurrentState);
// Not strictly functional here, but as always with
// this topic, a compromise is needed
this.CurrentState = newState;
// Have we completed the final iteration?
That's done
after
// reaching the end condition
if (stopIterating)
return false;
var endConditionMet =
this.endCondition(this.CurrentState);
var lastIteration = !this.stopIterating &&
endConditionMet;
this.stopIterating = endConditionMet;
return !this.stopIterating || lastIteration;
}
public void Reset()
{
// restore the initial state
this.CurrentState = this.StartState;
}
}
That’s the hard bit done!! We have an engine under the surface that’ll allow
us to iterate through successive states until we’re finished - whatever we
decide “finished” means.
Next item required is the IEnumerable to run the Enumerator. That’s
pretty straightforward:
public class GameIterator : IEnumerable<Game>
{
private readonly Game _startState;
private readonly Func<Game,Game> _iterator;
private readonly Func<Game,bool> _endCondition;
public GameIterator(Game startState, Func<Game, Game>
iterator,
Func<Game, bool> endCondition)
{
this._startState = startState;
this._iterator = iterator;
this._endCondition = endCondition;
}
public IEnumerator<Game> GetEnumerator() =>
new GameEnumerator(this._startState, this._iterator,
this._endCondition);
}
IEnumerator IEnumerable.GetEnumerator() =>
GetEnumerator();
}
Everything is now in place to carry out a custom iteration. I just need to
define my custom logic, set up the iterator.
var playerState = geState();
var rnd = getRandomNumberGenerator();
var endCondition = (Game x) => x.x.LastAction ==
Actions.PayFine ||
x.LastAction == Actions.GetOutOfJailFree ||
x.DieOne == x.DieTwo);
var update = (Game x) => {
var action = GetAction();
return action switch
{
Actions.PayFine => x with
{
Money = x.Money - 50,
LastAction = action
},
Actions.GetOutOfJailFree => x with
{
GetOutOfJail = x.GetOutOfJail - 1,
LastAction = action
},
_ => x with
{
DieOne = rnd.Random(1, 6),
DieTwo = rnd.Random(1, 6)
}
}
}
var gameIterator = new GameIterator(playerState, update,
endCondition);
There are a couple of options for how to handle the iteration itself, and I’d
like to take a little time out to discuss each of those options in a little
more detail.
Using Indefinite Iterators
Strictly speaking, as a fully-fledged Iterator any LINQ operation can be
applied, as well as a standard ForEach iteration.
ForEach would probably be the simplest way to handle this iteration, but
it wouldn’t be strictly functional. It’s up to you, if you want to compromise.
It might look like this:
foreach(var g in gameIterator)
{
// store the updated state outside of the loop.
playerState = g;
// Here you can do whatever logic you'd like to do
// to message back to the player.
Write a message onto
screen
// or whatever is useful for them to be prompted to do
another action
}
// At the end of the loop here, the player is now out of
jail, and
// the game can continue with the updatd version of
playerState;
That wouldn’t give me too many causes for concern in production code,
honestly. But, what we’ve done is negated all of the work we’ve put
into attempting to get rid of non-functional code from our codebase.
The other options involve the use of LINQ. As a fully-fledged
Enumerable, our GameIterator can have any LINQ operations applied to
it. Which ones would be the best, though?
Select would be an obvious starting place, but it might not entirely
behave as you’d expect. Usage is pretty much the same as any normal
Select list operation you’ve ever done before:
var gameStates = gameIterator.Select(x => x);
The trick here is that we’re treating gameIterator as an array, so Select -
ing from it will result in an array of game states. What you’ll basically have
is an array of every intermedate step the user has gone through, finishing with
the final state in the last element.
The easy way to reduce this down to simply the final state is to substitute
Select for Last:
var endState = var gameStates = gameIterator.Last();
This assumes, of course that you aren’t interested in the intermediate steps. It
might be that you want to compose a message to the user for each state
update, in which case you might want to select, and provide a transformation.
Something like this, perhaps:
var messages = gameIterator.Select(x =>
"You chose to do " + x.LastAction + " and are " +
(x.InJail ? "In Jail" : "Free to go!");
);
That eradicates the actual game state, though, so possibly Aggregate
might be a better option:
var stateAndMessages = (
Messages: Enumerable.Empty<string>(),
State: playerState
);
var updatedStateAndMessages =
stateAndMessages.Aggregate(stateAndMessages, (acc, x) => (
acc.Messages.Append("You chose to do " + x.LastAction + "
and are " +
(x.InJail ? "In Jail" : "Free to go!")),
x
));
As you saw in the previous section though, there’s no special reason that an
Enumerable has to start at the beginning and loop to the end. We can
make it behave in absolutely any way we care to.
What I want to do in this case, is - instead of an array - I want to pass in a
single state object of some kind, along with a bundle of code (i.e. a Thunk, or
Func delegate) for determining whether the loop should continue or not.
Working backwards, the first thing I’ll make is the Enumerator. This is an
entirely bespoke enumeration process, so I’m not going to make any effort to
make it generic in any way. The logic I’m writing wouldn’t make sense
outside of a game state object.
I might want to do several different iterations in my hypothetical Monopoly
implementation though, so I’ll make the operation and loop termination logic
somewhat generic.
public class GameEnumerator : IEnumerator<Game>
{
// I need this in case of a restart
private Game StartState;
private Game CurrentState;
// old game state -> new game state
private readonly Func<Game, Game> iterator;
// Should the iteration stop?
private Func<Game, bool> endCondition;
// some tricky logic required to ensure the final
// game state is iterated. Normal logic is that if
// the MoveNext function returns false, then there isn't
// anything pulled from Current, the loop simply
terminates
private bool stopIterating = false;
public GameEnumerator(Game state, Func<Game, Game>
iterator,
Func<Game, bool> endCondition)
{
this.StartState = state;
this.CurrentState = state;
this.iterator = iterator;
this.endCondition = endCondition;
}
public Game Current => this.CurrentState;
object IEnumerator.Current => Current;
public void Dispose()
{
// Nothing to dispose
}
public bool MoveNext()
{
var newState = this.iterator(this.CurrentState);
// Not strictly functional here, but as always with
// this topic, a compromise is needed
this.CurrentState = newState;
// Have we completed the final iteration?
That's done
after
// reaching the end condition
if (stopIterating)
return false;
var endConditionMet =
this.endCondition(this.CurrentState);
var lastIteration = !this.stopIterating &&
endConditionMet;
this.stopIterating = endConditionMet;
return !this.stopIterating || lastIteration;
}
public void Reset()
{
// restore the initial state
this.CurrentState = this.StartState;
}
}
That’s the hard bit done!! We have an engine under the surface that’ll allow
us to iterate through successive states until we’re finished - whatever we
decide “finished” means.
Next item required is the IEnumerable to run the Enumerator. That’s
pretty straightforward:
public class GameIterator : IEnumerable<Game>
{
private readonly Game _startState;
private readonly Func<Game,Game> _iterator;
private readonly Func<Game,bool> _endCondition;
public GameIterator(Game startState, Func<Game, Game>
iterator,
Func<Game, bool> endCondition)
{
this._startState = startState;
this._iterator = iterator;
this._endCondition = endCondition;
}
public IEnumerator<Game> GetEnumerator() =>
new GameEnumerator(this._startState, this._iterator,
this._endCondition);
}
IEnumerator IEnumerable.GetEnumerator() =>
GetEnumerator();
}
Everything is now in place to carry out a custom iteration. I just need to
define my custom logic, set up the iterator.
var playerState = geState();
var rnd = getRandomNumberGenerator();
var endCondition = (Game x) => x.x.LastAction ==
Actions.PayFine ||
x.LastAction == Actions.GetOutOfJailFree ||
x.DieOne == x.DieTwo);
var update = (Game x) => {
var action = GetAction();
return action switch
{
Actions.PayFine => x with
{
Money = x.Money - 50,
LastAction = action
},
Actions.GetOutOfJailFree => x with
{
GetOutOfJail = x.GetOutOfJail - 1,
LastAction = action
},
_ => x with
{
DieOne = rnd.Random(1, 6),
DieTwo = rnd.Random(1, 6)
}
}
}
var gameIterator = new GameIterator(playerState, update,
endCondition);
There are a couple of options for how to handle the iteration itself, and I’d
like to take a little time out to discuss each of those options in a little
more detail.
Using Indefinite Iterators
Strictly speaking, as a fully-fledged Iterator any LINQ operation can be
applied, as well as a standard ForEach iteration.
ForEach would probably be the simplest way to handle this iteration, but
it wouldn’t be strictly functional. It’s up to you, if you want to compromise.
It might look like this:
foreach(var g in gameIterator)
{
// store the updated state outside of the loop.
playerState = g;
// Here you can do whatever logic you'd like to do
// to message back to the player.
Write a message onto
screen
// or whatever is useful for them to be prompted to do
another action
}
// At the end of the loop here, the player is now out of
jail, and
// the game can continue with the updatd version of
playerState;
That wouldn’t give me too many causes for concern in production code,
honestly. But, what we’ve done is negated all of the work we’ve put
into attempting to get rid of non-functional code from our codebase.
The other options involve the use of LINQ. As a fully-fledged
Enumerable, our GameIterator can have any LINQ operations applied to
it. Which ones would be the best, though?
Select would be an obvious starting place, but it might not entirely
behave as you’d expect. Usage is pretty much the same as any normal
Select list operation you’ve ever done before:
var gameStates = gameIterator.Select(x => x);
The trick here is that we’re treating gameIterator as an array, so Select -
ing from it will result in an array of game states. What you’ll basically have
is an array of every intermedate step the user has gone through, finishing with
the final state in the last element.
The easy way to reduce this down to simply the final state is to substitute
Select for Last:
var endState = var gameStates = gameIterator.Last();
This assumes, of course that you aren’t interested in the intermediate steps. It
might be that you want to compose a message to the user for each state
update, in which case you might want to select, and provide a transformation.
Something like this, perhaps:
var messages = gameIterator.Select(x =>
"You chose to do " + x.LastAction + " and are " +
(x.InJail ? "In Jail" : "Free to go!");
);
That eradicates the actual game state, though, so possibly Aggregate
might be a better option:
var stateAndMessages = (
Messages: Enumerable.Empty<string>(),
State: playerState
);
var updatedStateAndMessages =
stateAndMessages.Aggregate(stateAndMessages, (acc, x) => (
acc.Messages.Append("You chose to do " + x.LastAction + "
and are " +
(x.InJail ? "In Jail" : "Free to go!")),
x
));
As you saw in the previous section though, there’s no special reason that an
Enumerable has to start at the beginning and loop to the end. We can
make it behave in absolutely any way we care to.
What I want to do in this case, is - instead of an array - I want to pass in a
single state object of some kind, along with a bundle of code (i.e. a Thunk, or
Func delegate) for determining whether the loop should continue or not.
Working backwards, the first thing I’ll make is the Enumerator. This is an
entirely bespoke enumeration process, so I’m not going to make any effort to
make it generic in any way. The logic I’m writing wouldn’t make sense
outside of a game state object.
I might want to do several different iterations in my hypothetical Monopoly
implementation though, so I’ll make the operation and loop termination logic
somewhat generic.
public class GameEnumerator : IEnumerator<Game>
{
// I need this in case of a restart
private Game StartState;
private Game CurrentState;
// old game state -> new game state
private readonly Func<Game, Game> iterator;
// Should the iteration stop?
private Func<Game, bool> endCondition;
// some tricky logic required to ensure the final
// game state is iterated. Normal logic is that if
// the MoveNext function returns false, then there isn't
// anything pulled from Current, the loop simply
terminates
private bool stopIterating = false;
public GameEnumerator(Game state, Func<Game, Game>
iterator,
Func<Game, bool> endCondition)
{
this.StartState = state;
this.CurrentState = state;
this.iterator = iterator;
this.endCondition = endCondition;
}
public Game Current => this.CurrentState;
object IEnumerator.Current => Current;
public void Dispose()
{
// Nothing to dispose
}
public bool MoveNext()
{
var newState = this.iterator(this.CurrentState);
// Not strictly functional here, but as always with
// this topic, a compromise is needed
this.CurrentState = newState;
// Have we completed the final iteration?
That's done
after
// reaching the end condition
if (stopIterating)
return false;
var endConditionMet =
this.endCondition(this.CurrentState);
var lastIteration = !this.stopIterating &&
endConditionMet;
this.stopIterating = endConditionMet;
return !this.stopIterating || lastIteration;
}
public void Reset()
{
// restore the initial state
this.CurrentState = this.StartState;
}
}
That’s the hard bit done!! We have an engine under the surface that’ll allow
us to iterate through successive states until we’re finished - whatever we
decide “finished” means.
Next item required is the IEnumerable to run the Enumerator. That’s
pretty straightforward:
public class GameIterator : IEnumerable<Game>
{
private readonly Game _startState;
private readonly Func<Game,Game> _iterator;
private readonly Func<Game,bool> _endCondition;
public GameIterator(Game startState, Func<Game, Game>
iterator,
Func<Game, bool> endCondition)
{
this._startState = startState;
this._iterator = iterator;
this._endCondition = endCondition;
}
public IEnumerator<Game> GetEnumerator() =>
new GameEnumerator(this._startState, this._iterator,
this._endCondition);
}
IEnumerator IEnumerable.GetEnumerator() =>
GetEnumerator();
}
Everything is now in place to carry out a custom iteration. I just need to
define my custom logic, set up the iterator.
var playerState = geState();
var rnd = getRandomNumberGenerator();
var endCondition = (Game x) => x.x.LastAction ==
Actions.PayFine ||
x.LastAction == Actions.GetOutOfJailFree ||
x.DieOne == x.DieTwo);
var update = (Game x) => {
var action = GetAction();
return action switch
{
Actions.PayFine => x with
{
Money = x.Money - 50,
LastAction = action
},
Actions.GetOutOfJailFree => x with
{
GetOutOfJail = x.GetOutOfJail - 1,
LastAction = action
},
_ => x with
{
DieOne = rnd.Random(1, 6),
DieTwo = rnd.Random(1, 6)
}
}
}
var gameIterator = new GameIterator(playerState, update,
endCondition);
There are a couple of options for how to handle the iteration itself, and I’d
like to take a little time out to discuss each of those options in a little
more detail.
Using Indefinite Iterators
Strictly speaking, as a fully-fledged Iterator any LINQ operation can be
applied, as well as a standard ForEach iteration.
ForEach would probably be the simplest way to handle this iteration, but
it wouldn’t be strictly functional. It’s up to you, if you want to compromise.
It might look like this:
foreach(var g in gameIterator)
{
// store the updated state outside of the loop.
playerState = g;
// Here you can do whatever logic you'd like to do
// to message back to the player.
Write a message onto
screen
// or whatever is useful for them to be prompted to do
another action
}
// At the end of the loop here, the player is now out of
jail, and
// the game can continue with the updatd version of
playerState;
That wouldn’t give me too many causes for concern in production code,
honestly. But, what we’ve done is negated all of the work we’ve put
into attempting to get rid of non-functional code from our codebase.
The other options involve the use of LINQ. As a fully-fledged
Enumerable, our GameIterator can have any LINQ operations applied to
it. Which ones would be the best, though?
Select would be an obvious starting place, but it might not entirely
behave as you’d expect. Usage is pretty much the same as any normal
Select list operation you’ve ever done before:
var gameStates = gameIterator.Select(x => x);
The trick here is that we’re treating gameIterator as an array, so Select -
ing from it will result in an array of game states. What you’ll basically have
is an array of every intermedate step the user has gone through, finishing with
the final state in the last element.
The easy way to reduce this down to simply the final state is to substitute
Select for Last:
var endState = var gameStates = gameIterator.Last();
This assumes, of course that you aren’t interested in the intermediate steps. It
might be that you want to compose a message to the user for each state
update, in which case you might want to select, and provide a transformation.
Something like this, perhaps:
var messages = gameIterator.Select(x =>
"You chose to do " + x.LastAction + " and are " +
(x.InJail ? "In Jail" : "Free to go!");
);
That eradicates the actual game state, though, so possibly Aggregate
might be a better option:
var stateAndMessages = (
Messages: Enumerable.Empty<string>(),
State: playerState
);
var updatedStateAndMessages =
stateAndMessages.Aggregate(stateAndMessages, (acc, x) => (
acc.Messages.Append("You chose to do " + x.LastAction + "
and are " +
(x.InJail ? "In Jail" : "Free to go!")),
x
));
As you saw in the previous section though, there’s no special reason that an
Enumerable has to start at the beginning and loop to the end. We can
make it behave in absolutely any way we care to.
What I want to do in this case, is - instead of an array - I want to pass in a
single state object of some kind, along with a bundle of code (i.e. a Thunk, or
Func delegate) for determining whether the loop should continue or not.
Working backwards, the first thing I’ll make is the Enumerator. This is an
entirely bespoke enumeration process, so I’m not going to make any effort to
make it generic in any way. The logic I’m writing wouldn’t make sense
outside of a game state object.
I might want to do several different iterations in my hypothetical Monopoly
implementation though, so I’ll make the operation and loop termination logic
somewhat generic.
public class GameEnumerator : IEnumerator<Game>
{
// I need this in case of a restart
private Game StartState;
private Game CurrentState;
// old game state -> new game state
private readonly Func<Game, Game> iterator;
// Should the iteration stop?
private Func<Game, bool> endCondition;
// some tricky logic required to ensure the final
// game state is iterated. Normal logic is that if
// the MoveNext function returns false, then there isn't
// anything pulled from Current, the loop simply
terminates
private bool stopIterating = false;
public GameEnumerator(Game state, Func<Game, Game>
iterator,
Func<Game, bool> endCondition)
{
this.StartState = state;
this.CurrentState = state;
this.iterator = iterator;
this.endCondition = endCondition;
}
public Game Current => this.CurrentState;
object IEnumerator.Current => Current;
public void Dispose()
{
// Nothing to dispose
}
public bool MoveNext()
{
var newState = this.iterator(this.CurrentState);
// Not strictly functional here, but as always with
// this topic, a compromise is needed
this.CurrentState = newState;
// Have we completed the final iteration?
That's done
after
// reaching the end condition
if (stopIterating)
return false;
var endConditionMet =
this.endCondition(this.CurrentState);
var lastIteration = !this.stopIterating &&
endConditionMet;
this.stopIterating = endConditionMet;
return !this.stopIterating || lastIteration;
}
public void Reset()
{
// restore the initial state
this.CurrentState = this.StartState;
}
}
That’s the hard bit done!! We have an engine under the surface that’ll allow
us to iterate through successive states until we’re finished - whatever we
decide “finished” means.
Next item required is the IEnumerable to run the Enumerator. That’s
pretty straightforward:
public class GameIterator : IEnumerable<Game>
{
private readonly Game _startState;
private readonly Func<Game,Game> _iterator;
private readonly Func<Game,bool> _endCondition;
public GameIterator(Game startState, Func<Game, Game>
iterator,
Func<Game, bool> endCondition)
{
this._startState = startState;
this._iterator = iterator;
this._endCondition = endCondition;
}
public IEnumerator<Game> GetEnumerator() =>
new GameEnumerator(this._startState, this._iterator,
this._endCondition);
}
IEnumerator IEnumerable.GetEnumerator() =>
GetEnumerator();
}
Everything is now in place to carry out a custom iteration. I just need to
define my custom logic, set up the iterator.
var playerState = geState();
var rnd = getRandomNumberGenerator();
var endCondition = (Game x) => x.x.LastAction ==
Actions.PayFine ||
x.LastAction == Actions.GetOutOfJailFree ||
x.DieOne == x.DieTwo);
var update = (Game x) => {
var action = GetAction();
return action switch
{
Actions.PayFine => x with
{
Money = x.Money - 50,
LastAction = action
},
Actions.GetOutOfJailFree => x with
{
GetOutOfJail = x.GetOutOfJail - 1,
LastAction = action
},
_ => x with
{
DieOne = rnd.Random(1, 6),
DieTwo = rnd.Random(1, 6)
}
}
}
var gameIterator = new GameIterator(playerState, update,
endCondition);
There are a couple of options for how to handle the iteration itself, and I’d
like to take a little time out to discuss each of those options in a little
more detail.
Using Indefinite Iterators
Strictly speaking, as a fully-fledged Iterator any LINQ operation can be
applied, as well as a standard ForEach iteration.
ForEach would probably be the simplest way to handle this iteration, but
it wouldn’t be strictly functional. It’s up to you, if you want to compromise.
It might look like this:
foreach(var g in gameIterator)
{
// store the updated state outside of the loop.
playerState = g;
// Here you can do whatever logic you'd like to do
// to message back to the player.
Write a message onto
screen
// or whatever is useful for them to be prompted to do
another action
}
// At the end of the loop here, the player is now out of
jail, and
// the game can continue with the updatd version of
playerState;
That wouldn’t give me too many causes for concern in production code,
honestly. But, what we’ve done is negated all of the work we’ve put
into attempting to get rid of non-functional code from our codebase.
The other options involve the use of LINQ. As a fully-fledged
Enumerable, our GameIterator can have any LINQ operations applied to
it. Which ones would be the best, though?
Select would be an obvious starting place, but it might not entirely
behave as you’d expect. Usage is pretty much the same as any normal
Select list operation you’ve ever done before:
var gameStates = gameIterator.Select(x => x);
The trick here is that we’re treating gameIterator as an array, so Select -
ing from it will result in an array of game states. What you’ll basically have
is an array of every intermedate step the user has gone through, finishing with
the final state in the last element.
The easy way to reduce this down to simply the final state is to substitute
Select for Last:
var endState = var gameStates = gameIterator.Last();
This assumes, of course that you aren’t interested in the intermediate steps. It
might be that you want to compose a message to the user for each state
update, in which case you might want to select, and provide a transformation.
Something like this, perhaps:
var messages = gameIterator.Select(x =>
"You chose to do " + x.LastAction + " and are " +
(x.InJail ? "In Jail" : "Free to go!");
);
That eradicates the actual game state, though, so possibly Aggregate
might be a better option:
var stateAndMessages = (
Messages: Enumerable.Empty<string>(),
State: playerState
);
var updatedStateAndMessages =
stateAndMessages.Aggregate(stateAndMessages, (acc, x) => (
acc.Messages.Append("You chose to do " + x.LastAction + "
and are " +
(x.InJail ? "In Jail" : "Free to go!")),
x
));
As you saw in the previous section though, there’s no special reason that an
Enumerable has to start at the beginning and loop to the end. We can
make it behave in absolutely any way we care to.
What I want to do in this case, is - instead of an array - I want to pass in a
single state object of some kind, along with a bundle of code (i.e. a Thunk, or
Func delegate) for determining whether the loop should continue or not.
Working backwards, the first thing I’ll make is the Enumerator. This is an
entirely bespoke enumeration process, so I’m not going to make any effort to
make it generic in any way. The logic I’m writing wouldn’t make sense
outside of a game state object.
I might want to do several different iterations in my hypothetical Monopoly
implementation though, so I’ll make the operation and loop termination logic
somewhat generic.
public class GameEnumerator : IEnumerator<Game>
{
// I need this in case of a restart
private Game StartState;
private Game CurrentState;
// old game state -> new game state
private readonly Func<Game, Game> iterator;
// Should the iteration stop?
private Func<Game, bool> endCondition;
// some tricky logic required to ensure the final
// game state is iterated. Normal logic is that if
// the MoveNext function returns false, then there isn't
// anything pulled from Current, the loop simply
terminates
private bool stopIterating = false;
public GameEnumerator(Game state, Func<Game, Game>
iterator,
Func<Game, bool> endCondition)
{
this.StartState = state;
this.CurrentState = state;
this.iterator = iterator;
this.endCondition = endCondition;
}
public Game Current => this.CurrentState;
object IEnumerator.Current => Current;
public void Dispose()
{
// Nothing to dispose
}
public bool MoveNext()
{
var newState = this.iterator(this.CurrentState);
// Not strictly functional here, but as always with
// this topic, a compromise is needed
this.CurrentState = newState;
// Have we completed the final iteration?
That's done
after
// reaching the end condition
if (stopIterating)
return false;
var endConditionMet =
this.endCondition(this.CurrentState);
var lastIteration = !this.stopIterating &&
endConditionMet;
this.stopIterating = endConditionMet;
return !this.stopIterating || lastIteration;
}
public void Reset()
{
// restore the initial state
this.CurrentState = this.StartState;
}
}
That’s the hard bit done!! We have an engine under the surface that’ll allow
us to iterate through successive states until we’re finished - whatever we
decide “finished” means.
Next item required is the IEnumerable to run the Enumerator. That’s
pretty straightforward:
public class GameIterator : IEnumerable<Game>
{
private readonly Game _startState;
private readonly Func<Game,Game> _iterator;
private readonly Func<Game,bool> _endCondition;
public GameIterator(Game startState, Func<Game, Game>
iterator,
Func<Game, bool> endCondition)
{
this._startState = startState;
this._iterator = iterator;
this._endCondition = endCondition;
}
public IEnumerator<Game> GetEnumerator() =>
new GameEnumerator(this._startState, this._iterator,
this._endCondition);
}
IEnumerator IEnumerable.GetEnumerator() =>
GetEnumerator();
}
Everything is now in place to carry out a custom iteration. I just need to
define my custom logic, set up the iterator.
var playerState = geState();
var rnd = getRandomNumberGenerator();
var endCondition = (Game x) => x.x.LastAction ==
Actions.PayFine ||
x.LastAction == Actions.GetOutOfJailFree ||
x.DieOne == x.DieTwo);
var update = (Game x) => {
var action = GetAction();
return action switch
{
Actions.PayFine => x with
{
Money = x.Money - 50,
LastAction = action
},
Actions.GetOutOfJailFree => x with
{
GetOutOfJail = x.GetOutOfJail - 1,
LastAction = action
},
_ => x with
{
DieOne = rnd.Random(1, 6),
DieTwo = rnd.Random(1, 6)
}
}
}
var gameIterator = new GameIterator(playerState, update,
endCondition);
There are a couple of options for how to handle the iteration itself, and I’d
like to take a little time out to discuss each of those options in a little
more detail.
Using Indefinite Iterators
Strictly speaking, as a fully-fledged Iterator any LINQ operation can be
applied, as well as a standard ForEach iteration.
ForEach would probably be the simplest way to handle this iteration, but
it wouldn’t be strictly functional. It’s up to you, if you want to compromise.
It might look like this:
foreach(var g in gameIterator)
{
// store the updated state outside of the loop.
playerState = g;
// Here you can do whatever logic you'd like to do
// to message back to the player.
Write a message onto
screen
// or whatever is useful for them to be prompted to do
another action
}
// At the end of the loop here, the player is now out of
jail, and
// the game can continue with the updatd version of
playerState;
That wouldn’t give me too many causes for concern in production code,
honestly. But, what we’ve done is negated all of the work we’ve put
into attempting to get rid of non-functional code from our codebase.
The other options involve the use of LINQ. As a fully-fledged
Enumerable, our GameIterator can have any LINQ operations applied to
it. Which ones would be the best, though?
Select would be an obvious starting place, but it might not entirely
behave as you’d expect. Usage is pretty much the same as any normal
Select list operation you’ve ever done before:
var gameStates = gameIterator.Select(x => x);
The trick here is that we’re treating gameIterator as an array, so Select -
ing from it will result in an array of game states. What you’ll basically have
is an array of every intermedate step the user has gone through, finishing with
the final state in the last element.
The easy way to reduce this down to simply the final state is to substitute
Select for Last:
var endState = var gameStates = gameIterator.Last();
This assumes, of course that you aren’t interested in the intermediate steps. It
might be that you want to compose a message to the user for each state
update, in which case you might want to select, and provide a transformation.
Something like this, perhaps:
var messages = gameIterator.Select(x =>
"You chose to do " + x.LastAction + " and are " +
(x.InJail ? "In Jail" : "Free to go!");
);
That eradicates the actual game state, though, so possibly Aggregate
might be a better option:
var stateAndMessages = (
Messages: Enumerable.Empty<string>(),
State: playerState
);
var updatedStateAndMessages =
stateAndMessages.Aggregate(stateAndMessages, (acc, x) => (
acc.Messages.Append("You chose to do " + x.LastAction + "
and are " +
(x.InJail ? "In Jail" : "Free to go!")),
x
));
As you saw in the previous section though, there’s no special reason that an
Enumerable has to start at the beginning and loop to the end. We can
make it behave in absolutely any way we care to.
What I want to do in this case, is - instead of an array - I want to pass in a
single state object of some kind, along with a bundle of code (i.e. a Thunk, or
Func delegate) for determining whether the loop should continue or not.
Working backwards, the first thing I’ll make is the Enumerator. This is an
entirely bespoke enumeration process, so I’m not going to make any effort to
make it generic in any way. The logic I’m writing wouldn’t make sense
outside of a game state object.
I might want to do several different iterations in my hypothetical Monopoly
implementation though, so I’ll make the operation and loop termination logic
somewhat generic.
public class GameEnumerator : IEnumerator<Game>
{
// I need this in case of a restart
private Game StartState;
private Game CurrentState;
// old game state -> new game state
private readonly Func<Game, Game> iterator;
// Should the iteration stop?
private Func<Game, bool> endCondition;
// some tricky logic required to ensure the final
// game state is iterated. Normal logic is that if
// the MoveNext function returns false, then there isn't
// anything pulled from Current, the loop simply
terminates
private bool stopIterating = false;
public GameEnumerator(Game state, Func<Game, Game>
iterator,
Func<Game, bool> endCondition)
{
this.StartState = state;
this.CurrentState = state;
this.iterator = iterator;
this.endCondition = endCondition;
}
public Game Current => this.CurrentState;
object IEnumerator.Current => Current;
public void Dispose()
{
// Nothing to dispose
}
public bool MoveNext()
{
var newState = this.iterator(this.CurrentState);
// Not strictly functional here, but as always with
// this topic, a compromise is needed
this.CurrentState = newState;
// Have we completed the final iteration?
That's done
after
// reaching the end condition
if (stopIterating)
return false;
var endConditionMet =
this.endCondition(this.CurrentState);
var lastIteration = !this.stopIterating &&
endConditionMet;
this.stopIterating = endConditionMet;
return !this.stopIterating || lastIteration;
}
public void Reset()
{
// restore the initial state
this.CurrentState = this.StartState;
}
}
That’s the hard bit done!! We have an engine under the surface that’ll allow
us to iterate through successive states until we’re finished - whatever we
decide “finished” means.
Next item required is the IEnumerable to run the Enumerator. That’s
pretty straightforward:
public class GameIterator : IEnumerable<Game>
{
private readonly Game _startState;
private readonly Func<Game,Game> _iterator;
private readonly Func<Game,bool> _endCondition;
public GameIterator(Game startState, Func<Game, Game>
iterator,
Func<Game, bool> endCondition)
{
this._startState = startState;
this._iterator = iterator;
this._endCondition = endCondition;
}
public IEnumerator<Game> GetEnumerator() =>
new GameEnumerator(this._startState, this._iterator,
this._endCondition);
}
IEnumerator IEnumerable.GetEnumerator() =>
GetEnumerator();
}
Everything is now in place to carry out a custom iteration. I just need to
define my custom logic, set up the iterator.
var playerState = geState();
var rnd = getRandomNumberGenerator();
var endCondition = (Game x) => x.x.LastAction ==
Actions.PayFine ||
x.LastAction == Actions.GetOutOfJailFree ||
x.DieOne == x.DieTwo);
var update = (Game x) => {
var action = GetAction();
return action switch
{
Actions.PayFine => x with
{
Money = x.Money - 50,
LastAction = action
},
Actions.GetOutOfJailFree => x with
{
GetOutOfJail = x.GetOutOfJail - 1,
LastAction = action
},
_ => x with
{
DieOne = rnd.Random(1, 6),
DieTwo = rnd.Random(1, 6)
}
}
}
var gameIterator = new GameIterator(playerState, update,
endCondition);
There are a couple of options for how to handle the iteration itself, and I’d
like to take a little time out to discuss each of those options in a little
more detail.
Using Indefinite Iterators
Strictly speaking, as a fully-fledged Iterator any LINQ operation can be
applied, as well as a standard ForEach iteration.
ForEach would probably be the simplest way to handle this iteration, but
it wouldn’t be strictly functional. It’s up to you, if you want to compromise.
It might look like this:
foreach(var g in gameIterator)
{
// store the updated state outside of the loop.
playerState = g;
// Here you can do whatever logic you'd like to do
// to message back to the player.
Write a message onto
screen
// or whatever is useful for them to be prompted to do
another action
}
// At the end of the loop here, the player is now out of
jail, and
// the game can continue with the updatd version of
playerState;
That wouldn’t give me too many causes for concern in production code,
honestly. But, what we’ve done is negated all of the work we’ve put
into attempting to get rid of non-functional code from our codebase.
The other options involve the use of LINQ. As a fully-fledged
Enumerable, our GameIterator can have any LINQ operations applied to
it. Which ones would be the best, though?
Select would be an obvious starting place, but it might not entirely
behave as you’d expect. Usage is pretty much the same as any normal
Select list operation you’ve ever done before:
var gameStates = gameIterator.Select(x => x);
The trick here is that we’re treating gameIterator as an array, so Select -
ing from it will result in an array of game states. What you’ll basically have
is an array of every intermedate step the user has gone through, finishing with
the final state in the last element.
The easy way to reduce this down to simply the final state is to substitute
Select for Last:
var endState = var gameStates = gameIterator.Last();
This assumes, of course that you aren’t interested in the intermediate steps. It
might be that you want to compose a message to the user for each state
update, in which case you might want to select, and provide a transformation.
Something like this, perhaps:
var messages = gameIterator.Select(x =>
"You chose to do " + x.LastAction + " and are " +
(x.InJail ? "In Jail" : "Free to go!");
);
That eradicates the actual game state, though, so possibly Aggregate
might be a better option:
var stateAndMessages = (
Messages: Enumerable.Empty<string>(),
State: playerState
);
var updatedStateAndMessages =
stateAndMessages.Aggregate(stateAndMessages, (acc, x) => (
acc.Messages.Append("You chose to do " + x.LastAction + "
and are " +
(x.InJail ? "In Jail" : "Free to go!")),
x
));
As you saw in the previous section though, there’s no special reason that an
Enumerable has to start at the beginning and loop to the end. We can
make it behave in absolutely any way we care to.
What I want to do in this case, is - instead of an array - I want to pass in a
single state object of some kind, along with a bundle of code (i.e. a Thunk, or
Func delegate) for determining whether the loop should continue or not.
Working backwards, the first thing I’ll make is the Enumerator. This is an
entirely bespoke enumeration process, so I’m not going to make any effort to
make it generic in any way. The logic I’m writing wouldn’t make sense
outside of a game state object.
I might want to do several different iterations in my hypothetical Monopoly
implementation though, so I’ll make the operation and loop termination logic
somewhat generic.
public class GameEnumerator : IEnumerator<Game>
{
// I need this in case of a restart
private Game StartState;
private Game CurrentState;
// old game state -> new game state
private readonly Func<Game, Game> iterator;
// Should the iteration stop?
private Func<Game, bool> endCondition;
// some tricky logic required to ensure the final
// game state is iterated. Normal logic is that if
// the MoveNext function returns false, then there isn't
// anything pulled from Current, the loop simply
terminates
private bool stopIterating = false;
public GameEnumerator(Game state, Func<Game, Game>
iterator,
Func<Game, bool> endCondition)
{
this.StartState = state;
this.CurrentState = state;
this.iterator = iterator;
this.endCondition = endCondition;
}
public Game Current => this.CurrentState;
object IEnumerator.Current => Current;
public void Dispose()
{
// Nothing to dispose
}
public bool MoveNext()
{
var newState = this.iterator(this.CurrentState);
// Not strictly functional here, but as always with
// this topic, a compromise is needed
this.CurrentState = newState;
// Have we completed the final iteration?
That's done
after
// reaching the end condition
if (stopIterating)
return false;
var endConditionMet =
this.endCondition(this.CurrentState);
var lastIteration = !this.stopIterating &&
endConditionMet;
this.stopIterating = endConditionMet;
return !this.stopIterating || lastIteration;
}
public void Reset()
{
// restore the initial state
this.CurrentState = this.StartState;
}
}
That’s the hard bit done!! We have an engine under the surface that’ll allow
us to iterate through successive states until we’re finished - whatever we
decide “finished” means.
Next item required is the IEnumerable to run the Enumerator. That’s
pretty straightforward:
public class GameIterator : IEnumerable<Game>
{
private readonly Game _startState;
private readonly Func<Game,Game> _iterator;
private readonly Func<Game,bool> _endCondition;
public GameIterator(Game startState, Func<Game, Game>
iterator,
Func<Game, bool> endCondition)
{
this._startState = startState;
this._iterator = iterator;
this._endCondition = endCondition;
}
public IEnumerator<Game> GetEnumerator() =>
new GameEnumerator(this._startState, this._iterator,
this._endCondition);
}
IEnumerator IEnumerable.GetEnumerator() =>
GetEnumerator();
}
Everything is now in place to carry out a custom iteration. I just need to
define my custom logic, set up the iterator.
var playerState = geState();
var rnd = getRandomNumberGenerator();
var endCondition = (Game x) => x.x.LastAction ==
Actions.PayFine ||
x.LastAction == Actions.GetOutOfJailFree ||
x.DieOne == x.DieTwo);
var update = (Game x) => {
var action = GetAction();
return action switch
{
Actions.PayFine => x with
{
Money = x.Money - 50,
LastAction = action
},
Actions.GetOutOfJailFree => x with
{
GetOutOfJail = x.GetOutOfJail - 1,
LastAction = action
},
_ => x with
{
DieOne = rnd.Random(1, 6),
DieTwo = rnd.Random(1, 6)
}
}
}
var gameIterator = new GameIterator(playerState, update,
endCondition);
There are a couple of options for how to handle the iteration itself, and I’d
like to take a little time out to discuss each of those options in a little
more detail.
Using Indefinite Iterators
Strictly speaking, as a fully-fledged Iterator any LINQ operation can be
applied, as well as a standard ForEach iteration.
ForEach would probably be the simplest way to handle this iteration, but
it wouldn’t be strictly functional. It’s up to you, if you want to compromise.
It might look like this:
foreach(var g in gameIterator)
{
// store the updated state outside of the loop.
playerState = g;
// Here you can do whatever logic you'd like to do
// to message back to the player.
Write a message onto
screen
// or whatever is useful for them to be prompted to do
another action
}
// At the end of the loop here, the player is now out of
jail, and
// the game can continue with the updatd version of
playerState;
That wouldn’t give me too many causes for concern in production code,
honestly. But, what we’ve done is negated all of the work we’ve put
into attempting to get rid of non-functional code from our codebase.
The other options involve the use of LINQ. As a fully-fledged
Enumerable, our GameIterator can have any LINQ operations applied to
it. Which ones would be the best, though?
Select would be an obvious starting place, but it might not entirely
behave as you’d expect. Usage is pretty much the same as any normal
Select list operation you’ve ever done before:
var gameStates = gameIterator.Select(x => x);
The trick here is that we’re treating gameIterator as an array, so Select -
ing from it will result in an array of game states. What you’ll basically have
is an array of every intermedate step the user has gone through, finishing with
the final state in the last element.
The easy way to reduce this down to simply the final state is to substitute
Select for Last:
var endState = var gameStates = gameIterator.Last();
This assumes, of course that you aren’t interested in the intermediate steps. It
might be that you want to compose a message to the user for each state
update, in which case you might want to select, and provide a transformation.
Something like this, perhaps:
var messages = gameIterator.Select(x =>
"You chose to do " + x.LastAction + " and are
" + (x.InJail ? "In Jail" : "Free to go!");
);
That eradicates the actual game state, though, so possibly
Aggregate might be a better option:
var stateAndMessages = (
Messages:
Enumerable.Empty<string>(),
State: playerState
);
var updatedStateAndMessages =
stateAndMessages.Aggregate(stateAndMessages, (acc,
x) => (
acc.Messages.Append("You chose to do " +
x.LastAction + " and are " +
(x.InJail ? "In Jail" :
"Free to go!")), x
));