Writing functional programming can induce a Zen like experience. With clean, short blocks of code that reveal their intent and inner workings plainly to you functional C# untangles the knots, and declutters the space.

No more side effects

Take a deep breath in. Hold it for 5 seconds. Exhale.

It's time to think functionally, and it's time to say goodbye to those nasty, no-good side effects.

alt text

  • Side effects occur when you modify state outside of your current scope, mutating state unknowingly somewhere else in the program. This leads to unwanted behaviour, and unwanted cause-and-effects.
  • Instead prefer functions that don't have side effects. These functions are known as pure functions. (disclaimer: writing pure functions is quite addictive - once you start you just can't stop)

The Zen Code Advises:

AVOID: Impure functions

cs public void UpdatePrice(decimal vat, decimal cost, decimal markup) { this.price = (cost + markup) * (1 + vat); }

PREFER: Pure functions

```cs public decimal PriceIncludingVat(decimal vat, decimal cost, decimal markup) { return (cost + markup) * (1 + vat); }

price = PriceIncludingVat(0.2m, 10m, 2m); ```

Calling PriceIncludingVat doesn't modify existing state; it returns new state. You can call it as many times as you want and your current price won't be affected until you actually set it.

Practice creating pure functions out of longer impure methods. Break the side effects out of methods and turn them into their own functions returning new state. You may find yourself untangling some really, nasty messes - it's cathartic and brings you closer to Zen.

Immutability

Close your eyes. Breathe in. Breath out. Embrace the tranquillity of immutability.

alt text

No longer will your state be mutable. In with the new, and out with the old. By making your objects immutable, you ensure that nothing, within any scope whatsoever, can change them. This prevents side effects altogether. The only way to achieve a changed property on an immutable object is to replace that object with a new one that contains the change.

The Zen Code Advises:

AVOID: Mutable Objects

```cs public class ZenGarden { public int Tranquillity { get; set; } // mutable public int Peace { get; set; } // mutable

public ZenGarden(int tranquillity, int peace)
{
    Tranquillity = tranquillity;
    Peace = peace;
}

} ```

This leads to

cs var garden = new ZenGarden(10, 20); garden.Peace = -1000; // or even worse public int TranquilityAndPeace(ZenGarden garden) { garden.Peace -= 1; // a side effect return garden.Tranquillity + garden.Peace; }

PREFER:

```cs public class ZenGarden { public readonly int Tranquillity; public readonly int Peace;

public ZenGarden(int tranquillity, int peace)
{
    Tranquillity = tranquillity;
    Peace = peace;
}

} ```

This leads to

cs var garden = new ZenGarden(10, 20); garden = new ZenGarden(10, 21); // peace goes up, because of immutability :] // pure function public int TranquilityAndPeace(ZenGarden garden) { var calculatedGarden = new ZenGarden(garden.Tranquillity, garden.Peace - 1); return calculatedGarden .Tranquillity + calculatedGarden .Peace; }

  • Note, readonly is used instead of a private setter to ensure that the values can't be changed even within the class itself.

No more worries about unwanted changes (side effects) - immutability ensures that nothing is mutating the same state, wave a friendly goodbye to race conditions and thread locks too.

Referential Transparency

Embrace the Zen of clarity. A referentially transparent function can be replaced by the value that it returns when it's called. It returns the same value for the same arguments regardless of its context. Referentially opaque functions do the opposite - usually due to referencing some external value which may change.

Referential transparency helps the code to read cleaner. It untangles functions that grab values from outside of their scope, and restricts them to act only on their parameters when calculating their return values.

It isolates functions, protecting them from external changes in code.

alt text

The Zen Code Advises:

AVOID: Opaque functions

cs public double PriceOfFood(double price) { // if the number of people changes, the price of food changes // regardless of price changing return this.numberOfPeople * price; }

PREFER: Transparent functions

cs public double PriceOfFood(double price, int numberOfPeople) { return numberOfPeople * price; }

Higher-Order Functions

It's first-class (functions) baby all the way. Let's pick those functions up and start treating them like the (first-class) citizens they are. C# treats functions like first-class citizens. This means that functions can be used as arguments to methods; functions can be assigned to variables; and function can even be returned from other functions.

Using functions as first-class citizens allows us to break our code into small building blocks, each of which encapsulates a little bit of (hopefully clean, pure, and referentially transparent) functionality. These small blocks can be used in many combinations to get different functionality. They can be swapped out and interchanged as our requirements change with little impact on the code base.

alt text

Generate your functionality as you need it - don't write reams of code. Let the functions behave like the moving parts we know they are.

Higher-order functions take in functions as parameters, or return functions. Because C# treats functions as first-class citizens it allows as to create higher-order functions.

The Zen Code Advises:

AVOID: Unclear lambdas

cs var range = Enumerable.Range(-20, 20); range.Where(i => i % 2 == 0); range.Where(i => i % 5 != 0);

PREFER: Named functions

cs Func<int, bool> isMod(int n) => i => i % n == 0; range.Where(isMod(true, 2)); range.Where(!isMod(false, 5));

AVOID: Procedural functional calls (where applicable)

```cs public class Car {...}

public void ChangeOil(Car car) {...} public void ChangeTyres(Car car) {...} public void Refuel(Car car) {...}

public void PitStop(Car car) { ChangeOil(car); ChangeTyres(car); Refuel(car); }

PitStop(car); ```

PREFER: Dynamic function calls (where applicable)

```cs public class Car {...}

public void ChangeOil(Car car) {...} public void ChangeTyres(Car car) {...} public void Refuel(Car car) {...}

public void PitStop(Car car, IEnumerable> pitstopRoutines) { foreach(var routine in pitstopRoutines) routine(car); }

PitStop(car, new List>{ChangeOil, ChangeTypes, Refuel}); `` The methodPitStop` is much more extensible. It can easily be extended and should hardly ever need modifying. This is achieved by simply passing in the functions you want to execute as parameters, treating them like first-class citizens.

Now go forth and embrace the Zen my dudes

alt text