Functional Programming 

in JavaScript

Parminder Singh

Frontend Web Developer

Agenda

  1. What is Functional Programming?
  2. Why Functional Programming? Pros & Cons
  3. Pure Functions - Referential Transparency
  4. Function Composition and Piping
  5. Function Shape
  6. Currying
  7. Partial Application
  8. Up close and personal with RamdaJS
  9. Ramda - Statements, Compose/Pipe, Lens, Conditionals
  10. Q/A

What is Functional Programing (FP)?

  • Programming paradigm
  • A way/style of programming
  • Two characteristics
    • ​Build programs by composing reusable Pure Functions
    • Write declarative code instead of imperative
  • Rewiring the thinking process
  • Relies on principles of Mathematics
  • Seeing FP patterns in writing a program
  • Not about using a third party library or framework

Imperative vs Declarative code

Imperative Code

Imperative Code

  • Read whole story to understand
  • Series of steps
  • Procedural Programming
  • No pure functions
  • Side effects

Declarative Code

Declarative Code

  • Well Modularized
  • Individual responsibility
  • Single Responsibility Principle (Design Pattern)
  • Pure Functions
  • No Side effects
  • Deduce the output in plain English
  • Readable and Reusable/Composable

Pure Functions

  • Given the same inputs, always returns the same output
  • Has no side-effects

Pure Functions

f(x) = 2x^2 + 3

x f(x)
0 3
1 5
2 11

Pure Functions

f(x) = 2x^2 + 3

Pure Functions

f(x) = 2x^2 + 3

function parabola(x) {
   return 2 * Math.pow(x, 2)  + 3
}


/* Tests */

expect(parabola(0)).toEqual(3); // Always true
expect(parabola(1)).toEqual(5); // Always true
expect(parabola(2)).toEqual(11); // Always true

Impure Functions & Side Effects

let count = 0;

function increaseCount(val) {
   count += val;
   return count;
}


increaseCount(1); // 1
increaseCount(1); // 2

count = 5;
increaseCount(1); // 6

Impure Functions & Side Effects

Math.random(); // => 0.4011148700956255
Math.random(); // => 0.8533405303023756
Math.random(); // => 0.3550692005082965



const time = () => new Date().toLocaleTimeString();
time(); // => "5:15:45 PM"

Referential Transparency

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

function mult(a, b) {
    return a * b;
}

var result = add(2, mult(3, 4)); // 14


// or

var result = add(2, 12); // 14
  • To ensure whether the function is pure or not
  • If you can replace a function call with its resulting value without changing the meaning of the program

Implementing FP

  • Building pure functions by using Pure functions
  • Compose functions from other functions
  • Code Modularisation and reusability
  • Higher Order function
  • Reducing Impurity surface area

Higher Order Function

(f o g)(x) or f(g(x))

function toggleModal(isOpen: boolean) {
  setModalOpen(isOpen);
}

function openModal() {
  toggleModal(true);  
}


function closeModal() {
  toggleModal(false);
}

Containing/Reducing Impurity

Containing/Reducing Impurity

Function Composition & Piping

Function Composition & Piping

(f o g)(x) or f(g(x))

Composition

Right to Left

Composition

Write code as an association of the functions rather than a series of imperative steps

Piping

$ wc -l * | sort -n | head -n 3

Piping

$ wc -l * | sort -n | head -n 3

Word Count  →  Sort Asc  →  Take top 3

Piping

Left to Right

Function Shape

  • Unary - 1 input
  • Binary - 2 inputs
  • n-ary - n inputs
const users = [
  { firstName: 'Jane', lastName: 'Doe' },
  { firstName: 'John', lastName: 'Doe' }
]

function getUserDisplayName(user) {
  return `${user.firstName} ${user.lastName}`;
}

users.map(user => getUserDisplayName(user)); // ["Jane Doe", "John Doe"]

Point Free Programming / Tacit Programming

const users = [
  { firstName: 'Jane', lastName: 'Doe' },
  { firstName: 'John', lastName: 'Doe' }
]

function getUserDisplayName(user) {
  return `${user.firstName} ${user.lastName}`;
}

users.map(getUserDisplayName); // ["Jane Doe", "John Doe"]

Point refers to the function argument 

Point Free Programming / Tacit Programming

👎

Currying

const multiply = ( a, b ) => a * b;

const mul = curry(multiply);

mul(2)(3);

Currying

👍

Currying - Partial Application

Currying - Partial Application

Partial Application utility

var multiply = (a, b) => a * b;

var double = partial(multiply, [2]);

double(2); //=> 4

Partial Application utility

var multiply = (a, b, c) => a * b * c;

var mul = partial(multiply, [2, 3]);

mul(2); //=> 12

RamdaJS

RamdaJS

Todo App Revamp

Installation

$ npm install ramda @types/ramda -S

// or

$ yarn add ramda @types/ramda

Usage

import * as R from 'ramda';  

// or 

import { curry, compose, pipe, partial } from 'ramda';

// or

const R = require('ramda');



R.curry(...)

R.compose(...)

R.pipe(...)

R.partial

R.partial

R.curry

Statements

R.equals

R.ifElse

R.path

Composition & Piping

R.compose

R.compose

1. It checks if the change event resulted in a check or uncheck of the checkbox.

2. Converts it to a boolean.

3. Gets the equivalent “todo” status value from the checked value.

4. Calls the onChange function to emit output to the parent React component.

R.compose (with TypeScript)

R.pipe

Lens

R.lensIndex

R.view

R.set

R.over

Conditionals

R.when

R.when

R.unless

R.x

257 functions

Ramda Interactive tutorial

  • Powerful Abstraction of code
  • Code reusability 
  • Deterministic code - less bugs
  • Excellent for testing
  • Easy debugging
  • Parallelism - BigData - MapReduce

Pros & Cons of FP

Pros

  • Not everything can be made Pure like I/O ops
  • Computers understand stateful imperative operations
  • Learning Curve
  • Little Verbose with Typescript
  • Dependency on third party libraries like Ramda

Cons

References

Thanks

Q/A

Functional Programming

By Param Singh

Functional Programming

  • 686