+ All Categories
Home > Internet > Functional es6

Functional es6

Date post: 16-Jul-2015
Category:
Upload: natalia-zaslavskaya
View: 317 times
Download: 1 times
Share this document with a friend
24
Sexier Javascript With Lodash & ES6 By Omry Nachman [[email protected]]
Transcript

Sexier JavascriptWith Lodash & ES6

ByOmry Nachman [[email protected]]

Agenda

Declarative Vs. Imperative

Functional Programming

Harness ES6 and Lodash

Functional best practices

Declarative ProgrammingDeclarative programming

focuses on the what * * *

Imperative programming focuses on the how

Imperative Codefunction followers(person, data) {

var result = [];

for (var i=0 ; i<data.length ; i++) {

if (data[i].follows.indexOf(person._id) >= 0 ) {

result.push(data[i]);

}

}

return result;

}

Declarative Code

var followers = (person, data) => _.where(data, {follows: [person._id]})

Functional Programming

Wikipediahttp://en.wikipedia.org/wiki/Function_%28mathematics%29

“In mathematics, a function is a relation between a set of inputs <domain> and a set of permissible outputs <range> with the property that each input is related

to exactly one output.”

Functions

f(x)=2x+3

round(x)

person => person’s mother

Not (Math) Functions

person => person’s child

function add(x) {this.sum += x; return this.sum;

}

function getSum(){return this.sum;

}

Math => Code Advantages of pure (===math style) functions

Constant output per input => Cacheable, Parallelizable

Composable => Single responsibility, Reusability, Great for DSLs

Known domain and range => Simplicity, Consistency

No side effects => Easy to test, Easy to reproduce

Enough TheoryLet’s look at some code patterns

Functional Approach

minFollowers = (min, data) => _.where(data, person => followers(person, data) >= min)

maxFollowers = (max, data) => _.where(data, person => followers(person, data) >= max)

rangeFollowers = (min, max, data) => maxFollowers(max, minFollowers(min, data))

Composition & Partial

rangeFollowers = (min, max, data) => _.compose( _.partial(maxFollowers, max), _.partial(minFollowers, min) )

DSLs

minFollowers = (min, data) => followersCount(isMoreThen(min), data)

maxFollowers = (max, data) => followersCount(lessThen(min), data)

rangeFollowers = (min, max, data) => followersCount(inRange(min, max), data)

Isn’t this syntax nice?

DSLs

moreThen = min => (val => val >= min)

lessThen = max => (val => value <= max),

inRange = (min, max) => (val => val>= min && val <= max)

followersCount = (filter, data) => _.where(data, person => filter(getFollowersOf(data, person._id))

It requires this bootstrapping:

So don’t get curried way…

Memoize

// O(2^n)var fib = n => (n<2) ? 1 : fib(n-2) + fib(n-1)

//O(n)var fib = _.memoize(n => (n<2) ? 1 : fib(n-2) + fib(n-1))

Pure functions can be memorised (cached) per input, trading CPU for memory

By default, the first argument is the cache key, but it can be customised

Immutability & Statelessness

setName = (obj, name) => { obj.name = name; }

withName = (obj, name) => _.merge(obj, {name: name})

No mutation, no side effects

Let’s Mess With Some DataThe functional way

Group Common Names

histogram = _(data). groupBy(person => person.name.first). mapValues(people => people.length). transform( (acc, count, name) => acc[count] = _.union(acc[count], [name])). value();

Say we want to create a histogram of people’s names

[{name:{first:’David’, last:’Jones’},…},{name:{first:’David’, last:’Kulas’},…},{name:{first:’Mia’, last:’Angelo’},…},{name:{first:’Lucia’, last:’Stroman’},…}]

{ 1:[‘Lucia’, ‘Mia’] 2:[‘David]}

Group Common *histogram = (data, predicate) => _(data). groupBy(predicate). mapValues(people => people.length). transform( (acc, count, name) => acc[count] = _.union(acc[count], [name])). value();

histogram(data, ’age’)

histogram(data, _.partialRight(followers, data))

So now we can do

Best Practices*And Worst Practices

Good Ideavar appState = {…} // hidden by closure, class or module

updateData = data => { // privileged method appState.data = data updateView(appState.data, appState.renderSettings, setView) }

updateState = newPartialState => { // privileged method appState = _merge(appState, newPartialState) updateView(appState.data, appState.renderSettings, setView) }goGetData().then(updateData)app.addEvenrListener(‘state-change’, updateState)

Access App State In One Place

Bad Idea

var myFunc = isVery => obscured => (because, i) => (just, learned) => about => functional => programming (and, arrow, notation) => but => maybe => iShould => breakeItDown.toSmaller.functions

Using functional style to make your code obscured

Questions?!?


Recommended