FUNCTIONAL PILLS FOR OO DEVELOPERS


Marco Perone

twitter.com/marcoshuttle

github.com/marcosh

marcosh.github.com

medium.com/@marcosh


red-blue-pill


What are FP and OOP?


Values

Basic principles, guiding precepts


Ideas

Technical ideas to realise values


Style

Coherent unions of values and ideas


OOP style

Encapsulation

Cohesiveness

Classes as data structures

Interfaces for abstraction


FP style

Correctness

Ability to reason about the code

Referential transparency

Compositionality

Everything is a value


Can we use some ideas of FP in OOP?


#1 Equational Reasoning


What does = mean?

a = f x

Can we interchange equal things?

a = f x

# is the program

g a

# equivalent to

g (f x)


Code as equations

Executing the code means solving a set of equations

Easy to reason about the code


How?

The only job of functions is returning a value

Same input => same output


#2 Immutability


Immutability

Never mutate the state of an object


Why?

What is the value of $name?

$person = new Person('Gigi', 'Zucon');

doSomethingToPerson($person);

$name = $person->name();

How?

Never mutate the state of an object

Always return a new copy

public function changeName($newName) : self
{
  $newPerson = clone $this;

  $newPerson->name = $newName;

  return $newPerson;
}

#3 Compositionality


Compositionality

Ensure composition is zero-cost operation


Benefit

Easy way to decompose and re-compose

Modularity


How?

Composition over inheritance? Not enough

Fluent interfaces? Meh…


Again, how?

Model your domain with compositional structures

Monoids, categories, …


And again, how?

Pure functions create naturally a category

Function composition as glue


#4 Everything is a value


Functions are values

$f = function (int $x) : int {return $x + 5;}

Programs are values

Programs as inputs/outputs of other programs


Abstraction

We can now abstract over inner computation

decorator : (a -> b) -> a -> b

continuation : a -> (a -> b) -> b

How?

Every modern language has lambdas

Be careful with the typing


#5 Make invalid states impossible


Avoid impossible states

Better model design

Reduce need for error handling


How?

Use the correct data structure

Value objects


How? (where you can)

Algebraic data types

data Player = First | Second

data Point = Love | Fiftween | Thirty

data Score
  = Points Point Point
  | Forty Player Point
  | Deuce
  | Advantage Player
  | Game Player

---

## How? (where you can't)

[Visitor pattern](https://blog.ploeh.dk/2018/06/25/visitor-as-a-sum-type/)

Named constructors

---

## #6 Good ad-hoc polymorphism <!-- .element: class="ideas" -->

---

## Aren't interfaces enough?

Mmmm... [no](https://diogocastro.com/blog/2018/06/17/typeclasses-in-perspective/)

---

## Extensibility

Ability to implement interfaces for classes out of our control

---

## Conditional implementation

```haskell
instance Eq a => Eq [a]

instance (Eq a, Eq b) => Eq (a, b)

Return type polymorphism

Optional<String>  fromJson(Json s) { ... }
Optional<Integer> fromJson(Json s) { ... }

Relation between types

class Cast a b where
  cast :: a -> b

class Mult a b c where
  mult :: a -> b -> c

So, how?

Sorry… ¯\_(ツ)_/¯

Take a look at typeclasses


#7 Abstract on abstractions


An example

sum : [Int] -> Int
sum []        = 0
sum (x :: xs) = x + sum xs

Generalise on the type

fold : (Monoid a) => [a] -> a
fold []        = 0
fold (x :: xs) = x + fold xs

Generalise on the data structure

fold : (Monoid a, Foldable t) => t a -> a

Higher-kinded types

Abstract on data structures


How?

Parametric polymorphism is not enough

Sorry… ¯\_(ツ)_/¯


#8 Effects as data


Effects as data

Control what your program can do, so that you can reason about it


What can this function do?

f : a -> b

What can this function do?

f : a -> IO b

What can this function do?

f : a -> State s b

What can this function do?

f : a -> Maybe (State s b)

What can this function do?

f : Member (MyEff a) r => a -> Eff r b

How?

Describe your effects as data structures


Failure

final class Maybe {
  private $isJust;
  private $value;

  static function just($value) : self
  static function nothing() : self

  function match(callable $onJ, callable $onN)
}

Asynchronicity

export interface Task<A> {
  (): Promise<A>
}

Ideas

Equational Reasoning

Immutability

Compositionality

Everything is a value

Make invalid states impossible

Good ad-hoc polymorphism

Abstract on abstractions

Effects as data


solong


Marco Perone

twitter.com/marcoshuttle

github.com/marcosh

marcosh.github.com

medium.com/@marcosh