class: center, middle, primary # Functional Programming Basic Introduction by Jeff Mair 2017 --- layout:true name: primary_template class:primary, content --- layout: true name:landscape_paradigms template:primary_template ### Landscape of Programming Paradigms --- template: landscape_paradigms A programming paradigm is a style of coding that may be dictated by the design of the programming language used or by the approach intentionally taken by the programmer. The most popular paradigms today are: * Procedural [imperative] * Object Oriented [imperative] * Functional [declarative] --- template: landscape_paradigms #### Tenets of Procedural Programming * Code is grouped into procedures * Code is written in an imperative manner, where each line explicitly shows how actions are taken * Uses variables to track state * State can be modified C is a popular procedural language --- template: landscape_paradigms #### Tenets of Object Oriented Programming * Code is organized into objects which may model some real thing * Objects contain _imperative_ functions but they also contain the _state_ of the object * Eg, _LightBulb_ object has state that could be _ON_ or _OFF_, and functions like _turnOn()_, _turnOff()_, etc. Java, C#, Python, Ruby, and Javascript are all popular Object Oriented languages --- template: landscape_paradigms #### Tenets of Functional Programming * Pure Functions * Higher Order Functions * Controlling Side Effects & Immutable Data * Declarative/Expression Style Haskell, Clojure, F#, Javascript, and to a lesser extent C# are functional programming languages --- template:primary_template ### FP - Pure Functions 1. Depends only on data that is passed in. 2. Performs no modifications, other than creating the return value. Example 1. ```Javascript // simple example: Add which sums two numbers // only relies on input arguments and modifies nothing function Add(a, b) { return a + b; } ``` --- template:primary_template ### FP - Pure Functions Cont'd Counter-example: The Array.push() method below is _not_ pure because it modifies the array being operated on. ```Javascript var items = []; items.push({my:'object'}) ``` A pure version of this might be: ```Javascript function purePush(arr, newItem) { // make a new array var arr2 = []; // copy the values over to the new array object arr.forEach(function(item) { arr2.push(item); }); // add the new value to the new array object arr2.push(newItem); // return the new array object return arr2; } var arr = ['hello']; // new array is created and the original one has the original data var arr2 = purePush(arr, 'world'); ``` --- template:primary_template ### FP - Higher Order Functions Often used is the phrase 'Functions as First Class Citizens' Functions can be... * assigned to variables * passed into other functions * returned from functions --- template:primary_template ### FP - Immutable Data * Immutable structures reduce complexity * You know that you aren't inadvertently mutating structures that you don't want to * Increases certainty, makes code easier to understand * Locking down data makes it easier to understand what is going on in the application at any point --- template:primary_template ### FP - Declarative Style #### Expressions vs Statements Statements are executed for side-effects while expressions produce a result. ```c-sharp // statements string posOrNeg; if (value > 0) posOrNeg = "positive"; else posOrNeg = "negative"; // expression string posOrNeg = value > 0 ? "positive" : "negative"; ``` * Expressions can be easily composed in other expressions in place of a variable or other value --- template:primary_template name:cpa ### Currying & Partial Application --- template:cpa #### Currying * Convert a function that accepts multiple parameters into a series of functions that accept only 1 parameter Eg. ```Javascript function Add(a) { return function(b) { return a + b; } } console.log(Add(2)(3)); // --> 5 ``` --- template:primary_template ### Currying & Partial Application #### Partial Application * Supply only 1 of multiple possible arguments to a function which results in another function returning which will later accept the rest (or at least some more) arguments. ```Javascript function Add(a) { return function(b) { return a + b; } } var addTwo = Add(2); console.log(addTwo(3)); // --> 5 ``` --- name:why_use_fp_1 template:primary_template ### Why use Functional Programming? --- name:why_use_fp_1 template:primary_template ### Why use Functional Programming? #### Because it makes your code easier to reason about --- name:why_use_fp_2 template:why_use_fp_1 _Pure Functions_ tend to be easier to reason about than functions that take input and alter state outside the function's scope --- name:why_use_fp_3 template:why_use_fp_2 _Declarative Code_ tends to be easier to reason about because it is mainly focused on _what_ to do rather than _what_ it does and _how_ it does it --- name:why_use_fp_4 template:why_use_fp_3 _Easier to test_. Since _pure functions_ do not depend on anything beyond the input parameters, tests are easier to setup. No need for complex application state to be setup before-hand --- name:why_use_fp_5 template:why_use_fp_4 _Parallel Execution_. Since _pure functions_ do not change state, they are natually well suited for parallel or asynchronous execution. Immutable state means no data sharing which means no race conditions. --- ### Testing Functions Once you know that individual pieces work, you can be sure that the larger pieces that are composed of those smaller pieces also works. --- template: primary_template ### Declarative Code with Function Chaining ```c# var items = new List
(); items .Sort() .Augment() .Etc(); ``` --- template: primary_template ### Links