# Looking at OO for a Pattern

We'll look at three examples of OO code to help us understand it's equivalent in FP code.

## Incrementing an Integer

Given this code:

``````a = 0;
x = a++;
y = a++;
z = a++;
// which we'll rewrite to use a function that receives an argument
a = 0;
x = getAndIncrement(a);
y = getAndIncrement(a);
z = getAndIncrement(a);
``````

`getAndIncrement` is an example of an impure function because it does not return the same value each time it is called. Moreover, `a`'s value changes over time, so that `a /= 0` at the end of our program. How might we write the same thing using pure functions? We'll demonstrate a few attempts and explain their problems before showing the final working solution

``````// we'll make the function pure
var add1 = (i) => i + 1;

a = 0;

// Values end states are:
a == 0
x == y == z == 1
``````

The problem is `add1` receives the wrong state as an argument. If we pass the returned state from our previous call into the next call, we can resolve this problem:

``````a = 0;

// Values end states are:
a == 0
x == 1
y == 2
z == 3
``````

At this point, we could do state manipulation using a recursive function...

``````runNTimes :: forall a. Int -> (a -> a) -> a -> a
runNTimes 0 _ output = output
runNTimes count func arg = runNTimes (count - 1) func (func arg)
``````

... but state manipulation is more complicated than that. What if we wanted to add 1 at one point and add 2 at another? What if we want to subtract 5 as well? In short, this approach does not work when we increase the complexity of the state manipulation. The next two examples will focus on a different kind of state manipulation.

## Random Number Generators

Given this code:

``````x = random.nextInt
y = random.nextInt
z = random.nextInt

// rewritten to use "function arg" syntax
x = nextInt(random);
y = nextInt(random);
z = nextInt(random);
``````

`nextInt` is an impure function because it does not return the same value each time it is called. How might we write the same thing using pure functions? We'll demonstrate a few attempts and explain their problems before showing the final working solution

``````// Assume that  `nextInt` is now pure...
x = nextInt(random);
y = nextInt(random);
// ... then 'x' ALWAYS equals 'y'
// A random number can sometimes be the same one as before,
// but this shouldn't always be true

// To make `x /= y`, we need a new `random` value, something like:
x = nextInt(random1);
y = nextInt(random2);
``````

The solution is to make `nextInt` return two things via the `Tuple a b` type

• the random int value
• a new value of `random`
``````(Tuple x random2) = nextInt(random1);
(Tuple y random3) = nextInt(random2);
``````

where `Tuple a b` is just a box that holds two values of the same/different types:

``````data Tuple a b = Tuple a b
``````

## Popping Stacks

We'll explain this idea once more using a different context: Stacks. In OO, we can write the following code:

``````// assuming we have a non-empty stack:
//   (top) [1, 2, 3, 4, 5] (bottom)
x = stack.pop // x == 1
y = stack.pop // y == 2
z = stack.pop // z == 3

// rewritten using "function arg" syntax
x = pop(stack);
y = pop(stack);
z = pop(stack);
``````

`pop` is an impure function as calling it will not return the same value each time it is called. How might we write the same thing using pure functions?

``````// Assume that  `nextInt` is now pure...
x = pop(stack);
y = pop(stack);
// ... we just popped the same value twice off of the stack
// so that 'x' is always the same value/object as 'y'
// In other words
pop(stack) == x == y == 1

// To make `y` == 2, we need a version of `stack` that will return `2`
// as its next value to `pop`. In other words, something like...
x = pop(originalStack);
y = pop(originalStack_withoutX);
``````

The solution is to make `pop` return two things via the `Tuple a b` type:

• the popped value
• a new version of `stack` without the popped value
``````(Tuple x originalStack_withoutX)    = pop(originalStack);
(Tuple y originalStack_withoutXorY) = pop(originalStack_withoutX);
``````

## Identifying the Pattern

Here's the solution we came up with:

``````(Tuple x random2) = randomInt(random1);
(Tuple y random3) = randomInt(random2);

(Tuple x originalStack_withoutX)    = pop(originalStack);
(Tuple y originalStack_withoutXorY) = pop(originalStack_withoutX);

// and generalizing it to a pattern, we get
(Tuple value1,  value2        ) = stateManipulation(value1);
(Tuple value2,  value3        ) = stateManipulation(value2);
(Tuple value3,  value4        ) = stateManipulation(value3);
// ...
(Tuple value_N, value_N_plus_1) = stateManipulation(valueN);
``````

Turning this into Purescript syntax, we get:

``````state_manipulation_function :: forall state value. (state -> Tuple value state)
``````