On Github faizhasim / faizhasim.github.io
Some Info
requestBillingDetails(allVendors) .then(compose(extractContacts, latePayment)) .then(sendEmailNotification) .catch(ConnectionException, handleConnectionError) .catch(handleGenericError);
Promise spec (pipelining)
var Employee = new function(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } Employee.prototype.fullName = fluent(function(){ return this.firstName + " " + this.lastName; }); Employee.prototype.applyLeave = fluent(function(from, to) { var leaveInfo = LeaveBuilder .by(this) .from(from) .to(to) .build(); LeaveSystem .submit(leaveInfo) .then(notifyManager()); });
var subsribersOfSocialMedias = [{ serviceName: 'facebook', count: 35433, hasOfficalSupport: true }, { serviceName: 'twitter', count: 25433, hasOfficalSupport: true }, { serviceName: 'instagram', count: 2348, hasOfficalSupport: false }];
Should give total count of 63214.
var total = 0; for (var i = 0; i < subsribersOfSocialMedias.length; i++) { total += subsribersOfSocialMedias[i].count; } console.log(total);
Imperative approach...
var subsriberCount = function(subsriberInfo) { return subsriberInfo.count; } var accumulate = function(previousValue, currentValue) { return previousValue + currentValue; } var total = subsribersOfSocialMedias .map(subsriberCount) .reduce(accumulate); console.log(total);
Functional approach...
var withOfficialSupport = function(officiallySupported) { return function(subsriberInfo) { return subsriberInfo.hasOfficalSupport === officiallySupported; } } var total = subsribersOfSocialMedias .filter(withOfficialSupport(true)) .map(subsriberCount) .reduce(accumulate);
And, to filter by the officially supported social medias.
Exact same code with CoffeeScript:
subsriberCount = (subsriberInfo) -> subsriberInfo.count withOfficialSupport = (officiallySupported) -> (subsriberInfo) -> subsriberInfo.hasOfficalSupport is officiallySupported total = subsribersOfSocialMedias .filter (withOfficialSupport true) .map subsriberCount .reduce ((a,b) -> a + b)
Wait, what about ECMAScript 6?
var subsriberCount = (subsriberInfo) => subsriberInfo.count var withOfficialSupport = (officiallySupported) => (subsriberInfo) => { return subsriberInfo.hasOfficalSupport === officiallySupported } let total = subsribersOfSocialMedias .filter(withOfficialSupport(true)) .map(subsriberCount) .reduce((a,b) => a + b)
CoffeeScript influenced TC-39 decision making.
Examples are using Lazy.js.
Sequence: Represent both Array and Object
Create new sequence whose elements are calculated from the supplied mapping function.
Lazy([1, 2, 3, 4, 5]).map(function(val) { return val * val; }).toArray(); // [1, 4, 9, 16, 25]
Create new sequence from the key property of of each element in the existing sequence
var subsribersOfSocialMedias = [{ serviceName: 'facebook', count: 35433, hasOfficalSupport: true }, { serviceName: 'twitter', count: 25433, hasOfficalSupport: true }, { serviceName: 'instagram', count: 2348, hasOfficalSupport: false }]; Lazy(subsribersOfSocialMedias).pluck('count').toArray(); // [35433, 25433, 2348]
Aggregation using an accumulator function
var counts = Lazy(subsribersOfSocialMedias).pluck('count'); counts.reduce(function(x, y) { return x + y; }); // 63214
counts.reduce(function(x, y) { return x + y; }, 0); // 63214
Exclude elements based on the supplied function
var noFacebook = function(obj) { if (obj.serviceName === 'facebook') { return true; } return false; } Lazy(subsribersOfSocialMedias) .reject(noFacebook) .toArray(); Lazy(subsribersOfSocialMedias) .reject(noFacebook) .reject({hasOfficalSupport: true}) .toArray();
Exclude elements based on the supplied function
var count = function(obj) { return obj.count; } Lazy(subsribersOfSocialMedias).sortBy(count).first(); // {serviceName: "instagram", count: 2348, hasOfficalSupport: false}
var sumOfSquares = function(x, y) { return (x × x) + (y × y); }
function(x, y) { return (x × x) + (y × y); }
Just a lambda (anonymous function)
Turning ((x,y) ⟼ (x × x) + (y × y))(5,2) into (((x,y) ⟼ (x × x) + (y × y))(5))(2)
Mathematically, if ƒ(x,y) = (x × x) + (y × y), then:
h(x) = y ⟼ ƒ(x,y)
h(x) = y ⟼ ƒ(x,y)
h(x) is a partial application of the full application.
Using allong.es at allong.es/try:
var curry = allong.es.curry; var giveGreetingFrom = curry(function(greeter, targetPerson) { return greeter + ' is saying "hi" to ' + targetPerson; }) var giveGreetingFromTom = giveGreetingFrom('Tom'); console.log(giveGreetingFromTom); // Will return unary partial application function console.log(giveGreetingFromTom('Bill')); // Tom is saying "hi" to Bill console.log(giveGreetingFrom('Tom', 'Bill')); // Tom is saying "hi" to Bill console.log(giveGreetingFrom('Tom')('Bill')); // Tom is saying "hi" to Bill
Shamelessly taken from allong.es/try.
var fluent = allong.es.fluent; Role = function () {}; Role.prototype.set = fluent( function (property, name) { this[property] = name }); var doomed = new Role() .set('name', "Fredo") .set('relationship', 'brother') .set('parts', ['I', 'II']); doomed //=> {"name":"Fredo","relationship":"brother","parts":["I","II"]}
var once = allong.es.once; var message = once( function () { return "Hello, it's me"; }); message() //=> "Hello, it's me" message() //=> undefined message() //=> undefined message() //=> undefined
Also available with underscore.
Continuation passing style of function as explained in Trampolines in JavaScript via raganwald.com
var trampoline = allong.es.trampoline, tailCall = allong.es.tailCall; function factorial (n) { var _factorial = trampoline( function myself (acc, n) { return n > 0 ? tailCall(myself, acc * n, n - 1) : acc }); return _factorial(1, n); }; factorial(10); //=> 3628800