functional javascript for everyone

41
Functional JavaScript for everyone Bartek Witczak

Upload: bartek-witczak

Post on 16-Apr-2017

333 views

Category:

Software


4 download

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]