Functional Programming
in JavaScript
Parminder Singh
Frontend Web Developer

Agenda
- What is Functional Programming?
- Why Functional Programming? Pros & Cons
- Pure Functions - Referential Transparency
- Function Composition and Piping
- Function Shape
- Currying
- Partial Application
- Up close and personal with RamdaJS
- Ramda - Statements, Compose/Pipe, Lens, Conditionals
- 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