1. Data should be immutable. Instead of manipulating data, you should make a new copy of it.
  2. Programs should be stateless. No function should care about what has happened in the past. functions are filters with pure input, pure output.

Functional programming uses Immutable Datastructures and doesn't rely on mutable state, this means that the functions have deterministic results.

Functional programming is easiest to use for stateless problems, e.g. programs that takes an input and generates an output without a need for side effects. Typical problem domains are compilers, libraries for calculations, and stateless servers.

Functional programming is primarily concerned with decomposing problems into functions that accept and return immutable values. Its usual structure is a collection of functions that transform values into other values, and various ways to combine functions. It avoids mutable state and does not require that the evaluation of functions occur in any particular order. Functional programming treats a program as a math problem rather than a series of operations(imperative). When faced with a problem, the functional question is "what values need to be transformed to solve this?"

haskell è un linguaggio che forza all uso del puro paradigma funzionale.

object-oriented languages are a better fit for GUIs.

mutability and State

What's 5 plus 2?
7.
Correct. What's 5 plus 3?
8
Nope. It's 10, because we turned 5 into 7, remember?

Monad

is a Type with methods returning a value of the same type

tipi comuni: Chain, Deferred, Promise, Maybe.

  • usate in Haskell per incorporare sideeffects, come I/O
  • jQuery objects are a monad
addition_monad myMonad().add(2).add(2).sum();
addition_monad.getInt();

Monad as a state container, allows you to simplify your logic as state-transforms

Maybe Monad to abstract away null values.

in haskel, lists are monads.

Unit tests creates additional contexts, in which main code can be used, thus they force to improve reusability of the code, thus code forced to make less or none side effects, thus programmer forced to rewrite code in functional style.

If something is supposed to, say, update something in the database, you abstract out an interface to the database and mock it out in your tests, and then use interaction tests to verify that your code is calling the right methods on your database abstraction.

whatever the language you're in, encapsulating side effects and state as much as possible, is going to be the way forward

"Testable code" is something that is simple to write unit tests for: if you encapsulate mutable state and have function outputs depend only upon inputs, your code suddenly becomes much easier to unit test.

Monads are useful when: 1. You have some kind of "container" for values, an object whose job it is to provide one or more values when you ask for them. 2. You don't want to ask for the value or values from the "container" every time you want to do something with them. 3. Nested "containers" are basically equivalent to a single container with the values from the leaf containers.

a Monad container has 3 behaviours: 1. A way to put a value into the monad, often called "unit". 2. A way to perform an operation on the values in the monad and return a new monad with the new values, called "map" 3. A way to flatten nested monads, called "bind" or "join" or "flatten".

Functor

Note that if you don't have a "flatten" operation, you have another kind of thing called a "functor". In non-functional languages, this distinction isn't so clear, and in dynamic languages the same object might behave both as if it were flattened and as if it were not. e.g Javascript promises appear to work this way, and there are several debates online as to wether they're functors or monads.

haskell Monad

{- | The 'Monad' class defines the basic operations over a /monad/,
a concept from a branch of mathematics known as /category theory/.
From the perspective of a Haskell programmer, however, it is best to
think of a monad as an /abstract datatype/ of actions.
Haskell's @do@ expressions provide a convenient syntax for writing monadic expressions.
 
Minimal complete definition: '>>=' and 'return'.
 
Instances of 'Monad' should satisfy the following laws:
 
  return a >>= k  ==  k a
  m >>= return  ==  m
  m >>= (\x -> k x >>= h)  ==  (m >>= k) >>= h
 
 
Instances of both 'Monad' and 'Functor' should additionally satisfy the law:
 
 fmap f xs  ==  xs >>= return . f
 
 
The instances of 'Monad' for lists, 'Data.Maybe.Maybe' and 'System.IO.IO'
defined in the "Prelude" satisfy these laws.
-}

https://github.com/ircmaxell/monad-php/blob/master/lib/MonadPHP/Monad.php

abstract class Monad {
    protected 
$value;
    public function 
__construct($value) {
        
$this->value $value;
    }
    
// put a value in the monad
    public static function unit($value) {
        if (
$value instanceof static) {
            return 
$value;
        }
        return new static(
$value);
    }
    
// apply a callback to all values
    public function bind($function, array $args = array()) {
        return 
$this::unit($this->runCallback($function$this->value$args));
    }
    
// get the current value inside the container
    public function extract() {
        if (
$this->value instanceof self) {
            return 
$this->value->extract();
        }
        return 
$this->value;
    }
    protected function 
runCallback($function$value, array $args = array()) {
        if (
$value instanceof self) {
            return 
$value->bind($function$args);
        }
        
array_unshift($args$value);
        return 
call_user_func_array($function$args);
    }
}