Functional Programming
with
JavaScript
JavaScript?
ES6+
Not quite what you run in your browsers
If anyone has issues understanding syntax, interrupt or ask!
Functional Programming?
Focus on functions and transformations instead of imperative steps
First Class Functions

Stateless

Pure Functions

Compatible with OOP

But like, why though?

Code gets
Clearer
Concise
Cleaner to refactor
This talk is titled Functional Programming
with JavaScript
First Class Functions
// Define functions on their own
const addOne = (x) => x + 1
const two = addOne(1)
const someNumbers = [1, 2, 3]
// Pass functions as arguments
const someBiggerNumbers = someNumbers.map(addOne)
// [2, 3, 4]
// Return functions from functions
const createAddFunction = (x) => {
return (y) => y + x
}
const addUno = createAddFunction(1)Stateless
// Error prone
const badProcessStudents = (students) => {
addExtraCredit(students)
curve(students)
markFailing(students)
return students
}
// Less error prone
const goodProcessStudents = (students) => {
const ecStudents = addExtraCredit(students)
const curvedStudents = curve(ecStudents)
const pfStudents = markFailing(curvedStudents)
return pfStudents
}Stateless with Spread
const badUpdateGrade = (student) => {
student.grade = 10
}
const goodUpdateGrade = (student) => {
return {...student, grade: 10}
}
const badAddStudent = (students, student) => {
students.push(student)
}
const goodAddStudent = (students, student) => {
return [...students, student]
}
Pure Functions
// Don't do this!
const curve = 1.10
const badCurve = (students) => {
for (student of students) {
student.grade = student.grade * curve
}
return students
}
// Do this
const goodCurve = (students, curve) => {
students.map(student => {
return {...student, grade: student.grade * curve}
})
}
Sometimes you
need more
Friendly Libraries


Immutable.js
Immutable
Cannot be changed after creation
Frees your mind from worrying about state
Enables lots of optimization techniques
Persistent
Allows for easy creation of updated objects
Relies on immutable data structures
Is actually fast
Immutable JS objects are both!
Immutable JS Basics
import Immutable from require('immutable');
var map1: Immutable.Map<string, number>;
map1 = Immutable.Map({a:1, b:2, c:3});
var map2 = map1.set('b', 50);
map1.get('b'); // 2
map2.get('b'); // 50
// This is potentially faster than the spread operator
// For sure less memory intensiveImmutable JS Justification
const students = [{name: "Kevin"}, {name: "Dan"}]
const gradedStudents = gradeStudents(students)
// What does gradedStudents look like?
// What does students look like?
const { List } = require('immutable')
const students = List([{name: "Kevin"}, {name: "Dan"}])
const gradedStudents = gradeStudents(students)
// What does gradedStudents look like?
// What does students look like?Const (final, not immutable)
// Some people call this immutable
const students = [{name: "Kevin"}, {name: "Dan"}]
// But you can still do these things
students.push({name: "Cedric"})
students[0]["name"] = "K-Dog"
// You just can't do this
students = []We have cooler data structures, now for cooler functions!
Ramda

Array.prototype is great!
Rambda is better
Rambda Basics
// Normal JS
const isUngraded = (task) => {
return !task.graded
}
// Normal JS with Rambda
const isRambdaUngraded = R.whereEq({graded: false})
const ungradedTasks = tasks.filter(isUngraded)
const rambdaUngraded = R.filter(isUngraded, tasks)
// Honestly, the benefits aren't really clear... yetCurrying!



Currying
// Normal JS
const getUngradedTasks = (tasks) => {
return tasks.filter(isUngraded)
}
// Rambda
const getRambdaUngradedTasks = R.filter(isUngraded)
// No tasks?!?!
// That's currying!Composability

Composability
const isGraded = R.whereEq({graded: true})
const hasZero = R.whereEq({grade: 0})
const isIncomplete = R.compose(isGraded, hasZero)
const getIncomplete = R.filter(isIncomplete)
const getParentEmail = R.pluck("parentEmail")
const getSadEmails = R.compose(getParentEmail, getIncomplete)A Function for Everything

"But JavaScript is for visual things!"


FP on the Front End
Original Advocate

Data goes in, HTML comes out
Username Display
const StudentHeader = ({ username }) => {
return <p>The logged in student is: {username}</p>
}
How do we manage all these stateless components?


They all can do this


You have to squint a bit and work hard with Ember
“I thought FP had to do with types?”

FP has to do with transformations
Types help you understand transformations
const gradedStudents = gradeStudents(students)
// What does gradedStudents look like?
// What does students look like?
const { List } = require('immutable')
const gradedStudents = gradeStudents(students)
// What does gradedStudents look like?
// What does students look like?
Enter
Basically, JS + Types
interface Student {
name: string;
graded: boolean;
grade: number;
parentEmail: string;
}
const kevin: Student = {
name: "Kevin",
graded: true,
grade: 75,
parentEmail: "kevinsdad@hotmail.com"
}
const gradeStudents: (students: Student[]): Student[] => {
...
}Great Editor Support

Defensive Coding

Lots more stuff!
- Union Types
- Type Aliases
- Intersection Types
- Type Guards
- Decorators
- (sometimes build issues)
- and more!
But does it have monoids in the category of endofunctors?!?!
Enter Fantasyland

Fantasy Land gives you the tools to effectively describe all sorts of transformations

Honestly, wait until you're really curious before exploring more.
These tools are neat, but are NOT NECESSARY for functional programming and add a lot of JavaScript
Why limit yourself?
Transpilation!
Because compilation isn't a cool enough word

Text
Lots of options

Elm Example
import Html exposing (beginnerProgram, div, button, text)
import Html.Events exposing (onClick)
main =
beginnerProgram { model = 0, view = view, update = update }
view model =
div []
[ button [ onClick Decrement ] [ text "-" ]
, div [] [ text (toString model) ]
, button [ onClick Increment ] [ text "+" ]
]
type Msg = Increment | Decrement
update msg model =
case msg of
Increment ->
model + 1
Decrement ->
model - 1
ClojureScript Example
(ns example
(:require [reagent.core :as r]))
(def click-count (r/atom 0))
(defn counting-component []
[:div
"The atom " [:code "click-count"] " has value: "
@click-count ". "
[:input {:type "button" :value "Click me!"
:on-click #(swap! click-count inc)}]])


Before we end, chill

Functional Programming
- Use functions that don't modify or depend on state
- Chain functions to make complex processes
- Focus on the transformation of items
- Do not focus on the imperative steps
Thanks!
Questions?
Functional Programming with JavaScript
By Kevin Greene
Functional Programming with JavaScript
- 319