02 Functional Programming

Functional Programming

  • Not actually a pattern, rather a paradigm
  • Based on Math & backed by Math (λ-theory)
  • But Math is not (necessarily) required for applying it

Don't fear FP, embrace it instead.

We won't do any Math or λ in this course
Still, a little bit of theory is necessary ...

Function

A function is a process which takes some input, called arguments, and produces some output called a return value.

fn(in) => out

Purpose of a function

  • mapping - A function maps input values to output values.​
  • procedure - A function may perform a sequence of steps.
  • i/o - A function may communicate with other parts of the system -> Side Effects

Functions( ) { }

Function Declaration

                
                    sum(4, 9); // 13

                    function sum(a, b) {
                        return a + b;
                    }

                    sum(4, 9); // 13
                
                

Functions ( ) { }

Function Expression

                
                    sum(1, 3); // TypeError: undefined is not a function

                    const sum = function(a, b) {
                        return a + b;
                    }

                    sum(1, 3); // 4
                
                

Functions ( ) { }

Arrow functions

                
                    const arrowFunction = () => console.log('arrow function');

                    // is almost the same as
                    const regularFunction = function() {
                        console.log('regular function')
                    }
                
                

Functions ( ) { }

Functions are "first-class" objects

                
                    function doThis(fn) {
                        fn();
                    }

                    function giveMeAFunction() {
                        return () => console.log('I am a function');
                    }
                
                

Higher Order Function

A function which takes a function as an argument, returns a function, or both.

Pure Function

Definition

  • … given the same input, will always return the same output.​
  • … produces no side effects.​

Pure Function

Definition

  • … does not rely on any external mutable state.​
  • … does not mutate external state.​

Impure Function

The very opposite of a pure function

"A dead giveaway that a function is impure is if it makes sense to call it without using its return value. For pure functions, that’s a noop."

Exercises

Pure or impure ? Why ?


                    let sum = function(a, b) {
                      return a + b;
                    };

                    let result = sum(1, 2);
                
pure => primitives are immutable

Pure or impure ? Why ?


                    var value1 = 1;
                    var value2 = 2;

                    let sum = function (a, b) {
                      return a + b;
                    };

                    let result = sum(value1, value2);
                
pure => primitives are immutable

Pure or impure ? Why ?


                    const value1 = 1;
                    var b = 2;

                    let sum = function (a, b) {
                      return a + b;
                    };

                    let result = sum(value1, b);
                
pure => primitives are immutable

Pure or impure ? Why ?


                    let a = 0;
                    let b = 1;

                    let sum = function(a, b) {
                      return a = a + b;
                    }

                    let result = sum(a, b);
                
pure => primitives are immutable
- assignment is part of function scope

Pure or impure ? Why ?


                    let a = 0;

                    let inc = function (a) {
                      return a++;
                    }

                    let result = inc(a);
                
pure => primitives are immutable

Pure or impure ? Why ?


                    var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];

                    let map = function (array) {
                      for (var i = 0; i < array.length; i++) {
                        setTimeout(() => array[i]++, 0);
                      }
                      return array;
                    }

                    let result = map(array);
                
impure => setTimeout is a side-effect
- array is resized
- array is mutable*

Pure or impure ? Why ?


                    const immutable = { a: 1, b: 2, c: 3 };

                    function mutate(object) {
                      return object;
                    }

                    let result = mutate(immutable);
                
1) pure => identity-function
2) impure => object is mutable*

Pure or impure ? Why ?


                    const array = [8, 4, 1, 6, 8, 0];

                    function sort(list) {
                      console.log("sorted:" + (list = list.slice().sort()));
                      return list;
                    }

                    let result = sort(array);
                
impure => console.log is a side-effect

Pure or impure ? Why ?


                    function log() {
                      console.log("Hello World");
                    }

                    function doSomething(fn) {
                      if (1 === 0) {
                        fn();
                      }
                      return 1;
                    }

                    let result = doSomething(log);
                
pure => doSomething() is pure despite log() being impure

Pure or impure ? Why ?


                    function doNothing(fn) {
                          return fn;
                    }

                    let result = doNothing(Math.random);
                
pure => doNothing() is the identity-function
- Math.random (impure) is never performed

Pure or impure ? Why ?


                    function getDocument() {
                      return global.window.document;
                    }
                    getDocument()

                    let result = getDocument();
                
impure => accessing external/global scope

Pure or impure ? Why ?


                    function divide(dividend, divisor) {
                      if (divisor === 0) throw new Error("Can't divide by 0.");
                      return dividend / divisor;
                    }

                    let result = divide(1, 1);
                
impure => exceptions are side-effects

Properties of pure functions

  • deterministic
  • predictable
  • completely independent of outside state​
  • immune to bugs related to shared mutable state​

Properties of pure functions

  • "referentially transparent"

    = any call to a pure function can be replaced with its resulting value without changing the meaning of the program​

Use of pure functions

  • great candidates for parallel processing
  • easy to move around, refactor and reorganize
  • flexible and adaptable to future changes​
  • very easy + safe to reuse (no state, no side-effects)​

Pure functions are awesome !

How to get from an impure to a pure function ?

Is a conversion always possible ?

Exercises | Homework

No, but most impure functions can be written to be pure

Shades of Purity

  • Technically, there are no pure functions in a non purely functional language
  • However (almost) pure is good enough for functional-oriented languages

Famous Citation

"... using shared state being reliant on sequences which vary depending on indeterministic factors, the output is impossible to predict, and therefore impossible to test properly ..."

Famous Citation

"non-determinism = parallel processing + mutable state"
Martin Odersky​

Resources

Questions?