Functional Javascript, CVjs
-
Upload
kaw2 -
Category
Technology
-
view
673 -
download
2
description
Transcript of Functional Javascript, CVjs
![Page 1: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/1.jpg)
Talk Functional Javascript!
//+ CV.js :: September 18th, 2013
Kevin Welcher
![Page 2: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/2.jpg)
Shout Out
![Page 3: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/3.jpg)
Shout Out
Something about Camp?
![Page 4: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/4.jpg)
10k Feet
• [Underscore.js / Lodash.js]
• Functional Concepts
• Composition
• Currying
• [Demo]
![Page 5: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/5.jpg)
Underscore.jsLodash.js
![Page 6: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/6.jpg)
Highlights
• reduce
• map
• pluck
• filter
• find
![Page 7: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/7.jpg)
reduce
• The grandaddy, most iterators can be made out of reduce
• “Reduce a list to a new object”
![Page 8: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/8.jpg)
map
• Bread and butter iterator
• Used to transform a list of elements from one type to another
• Whatever is returned within the iterator is the new object
![Page 9: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/9.jpg)
pluck
• Iterates over a list of objects and returns a new list made of the specified property from each object
• A common use for map
• IE: plucking the name from an array of people objects
![Page 10: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/10.jpg)
filter
• Only allows values that pass a predicate into the new list
• As with all these methods, it returns copies of the data
![Page 11: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/11.jpg)
find
• Accepts a predicate and returns the first item that passes the predicate
![Page 12: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/12.jpg)
Much, much more...• Many predicates
(isArray, isNull, ...)
• keys / values
• groupBy
• result
• array methods
• union / intersection
• chain / compose
• extend / defaults
• simple templates
• pick / omit
![Page 13: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/13.jpg)
FP vs OO
• The language of the... language
• How complexity is hidden
• How data is stored
![Page 14: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/14.jpg)
Functional Concepts
![Page 15: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/15.jpg)
Function purity
• Deterministic
• Does not depend on external state
• Does not depend on IO
• Does not cause side effects
![Page 16: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/16.jpg)
Function purityvar View = Backbone.View.extend({ initialize: function() { this.generateList(); }, generateList: function() { this.list = new Backbone.Collection([ {name: 'sally'}, {name: 'joe'} ]); }});
![Page 17: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/17.jpg)
Function purityvar View = Backbone.View.extend({ initialize: function() { this.list = this.generateList(); }, generateList: function() { return new Backbone.Collection([ {name: 'sally'}, {name: 'joe'} ]); }});
![Page 18: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/18.jpg)
Functions as data
• First class citizens
• Identified by their returns
• Modifiable
![Page 19: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/19.jpg)
Functions as building blocks
Functions which consume the return value of the function that follows.
Composition:
![Page 20: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/20.jpg)
Functions as building blocks
a() b() c()
a(b(c(x))) === compose(a, b, c)(x)
Composition
![Page 21: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/21.jpg)
Functions as building blocks
function add1 (x) { return x + 1;}
var add3 = compose(add1, add1, add1);
add3(0);
//> 3
![Page 22: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/22.jpg)
Functions as building blocks
function add1 (x) { return x + 1;}
var add3 = compose(add1, add1, add1);
add3(0);
//> 3
0
![Page 23: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/23.jpg)
Functions as building blocks
function add1 (x) { return x + 1;}
var add3 = compose(add1, add1, add1);
add3(0);
//> 3
01
![Page 24: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/24.jpg)
Functions as building blocks
function add1 (x) { return x + 1;}
var add3 = compose(add1, add1, add1);
add3(0);
//> 3
012
![Page 25: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/25.jpg)
Functions as building blocks
function add1 (x) { return x + 1;}
var add3 = compose(add1, add1, add1);
add3(0);
//> 3
0123
![Page 26: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/26.jpg)
Functions as building blocks
function not (x) { return !x;}
var boolify = compose(not, not);
not(not({}));boolify({});
//> true
![Page 27: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/27.jpg)
Functions as building blocks
function addTitle (x) { return ‘Mr. ‘ + x;}
function addSalutation (x) { return ‘G’day, ‘ + x;}
var meetAndGreet = compose(addSalutation, addTitle);
addSalutation(addTitle('Baggins'));meetAndGreet('Baggins');
//> G’day, Mr. Baggins
![Page 28: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/28.jpg)
Functions as building blocks
function add (x, y) { return x + y;}
var add1 = compose(???);
//> profit
![Page 29: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/29.jpg)
Currying
“Taking a function that takes multiple arguments and transforming it to a chain of functions that accept a single
argument.” - Wikipedia
![Page 30: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/30.jpg)
Notation
//+ <method name> :: type -> type -> type
![Page 31: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/31.jpg)
Notation
//+ <method name> :: type -> type -> type
A function that take takes an argument and returns a value of type
![Page 32: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/32.jpg)
Notation
//+ <method name> :: type -> type -> type
A function that take takes an argument and returns a value of type
integer -> integer
A function that takes in a single argument of type integer
The return type of integer. Since nothing follows, it is the final return
![Page 33: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/33.jpg)
Notation
//+ <method name> :: type -> type -> type
A function that take takes an argument and returns a value of type
![Page 34: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/34.jpg)
Notation
//+ <method name> :: type -> type -> type
The ultimate return value of a function
![Page 35: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/35.jpg)
//+ not :: a -> boolean
function not (x) { return !x;}
not(true) //> false
![Page 36: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/36.jpg)
//+ not :: a -> boolean
function not (x) { return !x;}
not(true) //> false
The a (or any other lower case letter) means we don’t care about the type.
![Page 37: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/37.jpg)
//+ add :: a, a -> a function add(x, y) { return x + y;}
add(1, 2); //> 3
![Page 38: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/38.jpg)
//+ add :: a, a -> a function add(x, y) { return x + y;}
add(1, 2); //> 3
I am abusing notation :(
![Page 39: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/39.jpg)
“Taking a function that takes multiple arguments and transforming it to a chain of functions that accept a single
argument.” - Wikipedia
![Page 40: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/40.jpg)
//+ add :: a, a -> a
//+ add :: a -> a -> a
![Page 41: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/41.jpg)
//+ add :: a -> a -> a
function add(x) { return function (y) { return x + y; };}
add(1)(2); //> 3
ed
![Page 42: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/42.jpg)
//+ add :: a -> a -> a
function add(x) { return function (y) { return x + y; };}
add(1)(2); //> 3
ed
![Page 43: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/43.jpg)
//+ add :: a -> a -> a
//+ add :: 1 -> a -> a
//+ add1 :: integer -> integervar add1 = add(1);
add1(2); //> 3
![Page 44: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/44.jpg)
//+ add :: a -> a -> a
//+ add :: ‘Mr. ‘ -> a -> a //+ addTitle :: string -> stringvar addTitle = add('Mr. ');
addTitle('Baggins');//> Mr. Baggins
![Page 45: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/45.jpg)
Problem
![Page 46: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/46.jpg)
That _ is ugly
//+ add :: a -> a -> a
function add(x) { return function (y) { return x + y; };}
add(1)(2); //> 3
![Page 47: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/47.jpg)
autoCurry
A custom function that automatically curries for you.
For each parameter of a function, it returns a new function.
![Page 48: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/48.jpg)
That _ is ugly
//+ add :: a -> a -> a
var add = function(x, y) { return x + y;}.autoCurry();
add(1, 2); //> 3add(1)(2); //> 3 Awww yissss
![Page 49: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/49.jpg)
Cool Story Bru...
![Page 50: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/50.jpg)
Let Me Convince You With...
![Page 51: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/51.jpg)
More Examples!
![Page 52: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/52.jpg)
reduce
//+ reduce :: fn -> a -> array -> avar reduce = function (fn, start, list) { // ... }.autoCurry();
![Page 53: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/53.jpg)
reduce
//+ reduce :: fn -> a -> array -> avar reduce = function (fn, start, list) { // ... }.autoCurry();
function (cnrt, val, index, list) { // ...}
![Page 54: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/54.jpg)
Sum all the numbers in a list?
![Page 55: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/55.jpg)
var items = [1, 2, 3];
//+ reduce :: fn -> a -> array -> areduce(function (crnt, val, index, list) { return crnt + val;}, 0, items);
//> 6
![Page 56: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/56.jpg)
var items = [1, 2, 3];
//+ reduce :: fn -> a -> array -> areduce(function (crnt, val, index, list) { return crnt + val;}, 0, items);
//> 6
We don’t use these two arguments so we can omit them
![Page 57: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/57.jpg)
var items = [1, 2, 3];
//+ reduce :: fn -> a -> array -> areduce(function (crnt, val) { return crnt + val;}, 0, items);
//> 6
![Page 58: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/58.jpg)
var items = [1, 2, 3];
//+ reduce :: fn -> a -> array -> areduce(function (crnt, val) { return crnt + val;}, 0, items);
//> 6
This function looks familiar...
![Page 59: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/59.jpg)
//+ add :: a -> a -> a
var add = function(x, y) { return x + y;}.autoCurry();
![Page 60: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/60.jpg)
var items = [1, 2, 3];
//+ reduce :: fn -> a -> array -> areduce(function (x, y) { return x + y;}, 0, items);
//> 6
![Page 61: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/61.jpg)
var items = [1, 2, 3];
//+ reduce :: fn -> a -> array -> areduce(function (x, y) { return x + y;}, 0, items);
//> 6 Instead of inlining the function, just pass
the function’s pointer
![Page 62: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/62.jpg)
var items = [1, 2, 3];
//+ reduce :: fn -> a -> array -> areduce(add, 0, items);
//> 6
![Page 63: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/63.jpg)
var items = [1, 2, 3];
//+ reduce :: fn -> a -> array -> areduce(add, 0, items);
//> 6
Cool! But isn’t reduce curried? Can we make this into a generic function?
![Page 64: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/64.jpg)
var items = [1, 2, 3];
//+ reduce :: add -> 0 -> array -> a//+ sum :: array -> integervar sum = reduce(add, 0);
sum(items);//> 6
![Page 65: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/65.jpg)
Demo
https://gist.github.com/kaw2k/6312261
![Page 66: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/66.jpg)
Lessons Learned?
![Page 67: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/67.jpg)
Keep your methods short and to the point
It is easier to build things if your building blocks are small
![Page 68: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/68.jpg)
Stick your data as the last parameter
reduce = function (fn, starting value, data)
function (general, ..., specific)
![Page 69: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/69.jpg)
Optional parameters are hard
Make a general function and curry it to take optional stuff
![Page 70: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/70.jpg)
Functional purity is pretty cool
• Easier to maintain
• Easier to reason
• Easier to test
• Easier to transport
![Page 71: Functional Javascript, CVjs](https://reader033.fdocuments.net/reader033/viewer/2022052823/5550f408b4c905417d8b55cd/html5/thumbnails/71.jpg)
Obligatory Marketing
(We are hiring)