Top Banner
Functional JavaScript for everyone Bartek Witczak
41

Functional JavaScript for everyone

Apr 16, 2017

Download

Software

Bartek Witczak
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Functional JavaScript for everyone

Functional JavaScript for everyone

Bartek Witczak

Page 2: Functional JavaScript for everyone
Page 3: Functional JavaScript for everyone

1/320

http://te.xel.io/posts/2015-02-22-category-theory-and-human-behavior.html

Page 4: Functional JavaScript for everyone

https://prateekvjoshi.com/2014/11/01/functors-in-c/

Page 5: Functional JavaScript for everyone

Functions

Page 6: Functional JavaScript for everyone

function youngerThan(age, limit) { return age < limit }

Page 7: Functional JavaScript for everyone

function youngerThan(age) { return function(limit) { return age < limit } }

Page 8: Functional JavaScript for everyone

function youngerThan(age) { return function(limit) { return age < limit } }

const youngerThanMe = youngerThan(28)

...

people.map(youngerThanMe)

Page 9: Functional JavaScript for everyone

In programming language design, a first-class citizen (…) is an entity which supports all the operations generally available to

other entities. These operations typically include being passed as an argument, returned from a function, and assigned to a

variable

Page 10: Functional JavaScript for everyone

let languages = ['JavaScript', 'Scala', 'Go']

...

...

...

...

let divs = [] for(let i = 0; i < languages.length; i++) { divs.push(`<div>${langs[i]}</div>`) }

Page 11: Functional JavaScript for everyone

let languages = ['JavaScript', 'Scala', 'Go']

languages.push('Java') languages.push('Ruby') languages.splice(0, 3)

let divs = [] for(let i = 0; i < languages.length; i++) { divs.push(`<div>${languages[i]}</div>`) }

Page 12: Functional JavaScript for everyone

const languages = Immutable.List.of( ‘JavaScript', ‘Scala', ‘Go' )

...

...

let divs = [] for(let i = 0; i < languages.length; i++) { divs.push(`<div>${languages[i]}</div>`) }

Page 13: Functional JavaScript for everyone

• always evaluates to same result for the same input

• evaluation does not cause any semantically observable side effects

Pure function

Page 14: Functional JavaScript for everyone

let user = {...}

function createMessage(text) { const message = Db.save(text) return message }

function sendMessage(text) { const message = createMessage(text) const messageId = MessageService.send(message, user) return messageId }

IMPURE

Page 15: Functional JavaScript for everyone

function createMessage(Db, text) { const message = Db.save(text) return message }

function sendMessage(Db, MessageService, text, user) { const message = createMessage(Db, text) const messageId = MessageService.send(message, user) return messageId }

PURE

Page 16: Functional JavaScript for everyone

function createMessage(Db, text) { const message = Db.save(text) return message }

function sendMessage(Db, MessageService, text, user) { const message = createMessage(Db, text) const messageId = MessageService.send(message, user) return messageId }

Explicit dependency / Self-documenting

Page 17: Functional JavaScript for everyone

Testable

function createMessage(Db, text) { const message = Db.save(text) return message }

function sendMessage(Db, MessageService, text, user) { const message = createMessage(Db, text) const messageId = MessageService.send(message, user) return messageId }

Page 18: Functional JavaScript for everyone

Resonable

function createMessage(Db, text) { const message = Db.save(text) return message }

function sendMessage(Db, MessageService, text, user) { const message = createMessage(Db, text) const messageId = MessageService.send(message, user) return messageId }

Page 19: Functional JavaScript for everyone

The problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the

banana... and the entire jungle

Joe Armstrong, Erlang creator

Page 20: Functional JavaScript for everyone

Currying

Page 21: Functional JavaScript for everyone

f ( x, y ) === f ( x ) ( y )

Page 22: Functional JavaScript for everyone

function add(x, y) { return x + y }

add(2, 3)

function curried_add (x) { return function (y) { return x + y } }

curried_add(2)(3)

Page 23: Functional JavaScript for everyone

const increment = curried_add(1)

increment(5)

peopleAge.map(increment)

const add10 = curried_add(10)

add10(15)

Page 24: Functional JavaScript for everyone
Page 25: Functional JavaScript for everyone

export const create = (fetch) => { return { ...

post: (url, data, token) => { const secureHeader = token ? { 'SECURE-TOKEN': token } : {} return Q(fetch(url, { method: 'post', headers: _.assign({ 'Accept': 'application/json', 'Content-Type': 'application/json' }, secureHeader), body: JSON.stringify(data) })) }

... }

export default create(fetch)

Page 26: Functional JavaScript for everyone

const token = '1jflann24kh11;2114fanakf'

http.post(someURL, { user: 'Henry' }, token)

Page 27: Functional JavaScript for everyone

return { ...

post: (token, url, data) => { ...

post(token)(url)(data)

currying

Page 28: Functional JavaScript for everyone

const createSecured = (http, token) => { ...

post: http.post(token)

... }

sercureHttp.post(someURL)({ user: 'Henry' })

Page 29: Functional JavaScript for everyone

No more loops

Page 30: Functional JavaScript for everyone

const languages = ['JavaScript', 'Scala', 'Haskell']

const divs = [] for(let i = 0; i < languages.length; i++) { divs.push(`<div>${languages[i]}</div>`) }

const languages = ['JavaScript', 'Scala', 'Haskell']

const divs = languages.map(l => `<div>${l}</div>`)

Page 31: Functional JavaScript for everyone

const dimensions = [100, 231, 84]

const sum = 0 for(let i = 0; i < dimensions.length; i++) { sum += dimensions[i] }

const dimensions = [100, 231, 84]

const sum = dimensions.reduce((a, b) => a + b, 0)

Page 32: Functional JavaScript for everyone

const people = [{name: 'Henry', age: 21}, ... ]

const adults = [] for(let i = 0; i < people.length; i++) { if(people[i].age >= 18) { adults.push(people[i]) } }

const people = [{name: 'Henry', age: 21}, ... ]

const adults = people.filter(p => p.age >= 18)

Page 33: Functional JavaScript for everyone
Page 34: Functional JavaScript for everyone

Function composition

Page 35: Functional JavaScript for everyone

f(g(x)) === (f ∘ g)(x)

Page 36: Functional JavaScript for everyone

function compose(f, g) { return function(x) { return f(g(x)) } }

Page 37: Functional JavaScript for everyone

const add2 = (x) => x + 2 const multiplyBy2 = (x) => x * 2

multiplyBy2(add2(3))

const add2ThenMultiplyBy2 = compose(multiplyBy2, add2) add2ThenMultiplyBy2(3)

Page 38: Functional JavaScript for everyone

function convertToAlbums(json) { const artist = extractArtist(json) const album = ... return album }

function extractTracks(album) { const rawTracks = album.tracks const tracks = ... return tracks }

function trackElem(track) { return `<li>${track.name} - ${track.duration}</li>` }

const tracks = compose(extractTracks, convertToAlbums)

const tracksFromJson = compose(map(trackElem), tracks)

tracksFromJson(albumJson)

Page 39: Functional JavaScript for everyone
Page 40: Functional JavaScript for everyone
Page 41: Functional JavaScript for everyone

Bartek Witczak

@bartekwitczak

[email protected]