Zen and Functional C#
Tags: csharp, dotnet, functional, zen
Published: 2019-08-29 22:16:24

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](https://media.giphy.com/media/11QJgcchgwskq4/giphy.gif)

* [Side effects](https://en.wikipedia.org/wiki/Side_effect_(computer_science)) 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](https://en.wikipedia.org/wiki/Pure_function). (**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](https://en.wikipedia.org/wiki/Immutable_object).

![alt text](https://media.giphy.com/media/yzvVXSvrg7JxC/giphy.gif)

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](https://en.wikipedia.org/wiki/Race_condition) and [thread locks](https://en.wikipedia.org/wiki/Lock_(computer_science)) too.

## Referential Transparency

Embrace the Zen of clarity. A [referentially transparent](https://en.wikipedia.org/wiki/Referential_transparency) 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](https://media.giphy.com/media/o4wnEX6N0ENUc/giphy.gif)

### 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](https://en.wikipedia.org/wiki/First-class_citizen). 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](https://media.giphy.com/media/yidUzx2B2f0SXheXGE/giphy.gif)

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](https://en.wikipedia.org/wiki/Higher-order_function) 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<Action<Car>> pitstopRoutines)
{
    foreach(var routine in pitstopRoutines)
        routine(car);
}

PitStop(car, new List<Action<Car>>{ChangeOil, ChangeTypes, Refuel});
```
The method `PitStop` 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](https://media.giphy.com/media/3o7btSlEkVbvtjkW3K/source.gif)