Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
  • Login to see the comments

  • Be the first to like this

Fancy talk

  1. 1. Introducing ƒancyWriting functional javascript that can hit production
  2. 2. Write performant, stable, readable,debuggable, and production worthy codequickly.In short, to make life easier.I wont invoke complex vocabulary, math, andtheory; I dont need to.What is my goal here?
  3. 3. What is functional programming?● Avoids State● Emphasizes application of functions● Avoids side-effects● Combines functions● Solves problems conceptually (no loops)
  4. 4. What is fancy?Fancy is a mashup:a. Underscore.js functions (Jeremy Ashkenas)b. Functional.js features (Oliver Steele)c. 1-off pseudo-arrays much like a jQuery collectiond. And some other functions I felt were needed(chunk)FancyArray([1,2,3]).sortBy("%2");>>> [2, 1, 3]a bc
  5. 5. Wait, how do I use this?1. Construct a FancyArray([foo, bar]) from any array.Construct a FancyObject({foo: bar}) from an object.2. Call normal underscore functions on your FancyArray (or object).3. When one of those calls would return an array, it instead returns aFancyArray, thus allowing chaining. When one of underscores functionswould have returned an object, it instead returns a FancyObject.However, unlike underscores .chain method, these one-off objects act verymuch like normal arrays or objects.
  6. 6. And-Also, any function that takes another function as anargument (like map) can take a string to represent thatfunction as devised by Oliver SteeleFancyArray([1,2,3]).map("*2")>> [2,4,6]FancyArray([1,2,3]).map("12/x")>> [12,6,4]FancyArray([1,2,3]).map("x,y->x+y")>> [1,3,5]
  7. 7. Like this:var samplePeople = new FancyObject({0: {name: "Alice", age: 15, ranking: 3, team: 2},1: {name: "David", age: 25, ranking: 2, team: 1},2: {name: "Charlie", age: 32, ranking: 4, team: 1},3: {name: "Bob", age: 24, ranking: 1, team: 4}});samplePeople.values().sortBy(".age").pluck("name");>>>["Alice", "Bob", "David", "Charlie"]Returns a FancyArrayThough you may not seefrom the chrome consoleoutput, this is still aFancyArrayFunctional.js style function
  8. 8. How does that make my life easier?You can read your code left-to-right, like englishIts now shorter than declarative, with less ugly nesting.No pollution of public scope or prototypes.var samplePeople = { ... };// fancy - This is prettierFO(samplePeople).values().sortBy( ".age").pluck("name");// plain underscore - Than that_.chain(samplePeople).values().sortBy(function(p) { return p.age; }).pluck( "name").value();
  9. 9. Lets consider a sample problem● Not fibonacci● Not prime numbers● Not foobar or fizzbuzz.Evaluating poker hands.
  10. 10. How do poker hands work?1st - Hand Types:1. Straight Flush2. 4 of a kind3. Full-House4. Flush5. Straight6. 3 of a kind7. 2 Pair8. 1 Pair9. High card2nd - Card ValuesHow high are the cardsused to make up thehand?3rd - Card ValuesHow high are theremaining cards in thehand?
  11. 11. Example:Full House:3 Of 1 value2 Of another ValueBeats lower ranking hands(like a straight). Losesto higher-ranking hands.(Straight flush).If two full houses happen, compare the sets of 3, whichever has the highervalue wins. If those are equal, compare the pairs of two, whichever has thehigher value wins. If those are equal, then the hands are equal.
  12. 12. A lame approach// A non-functional approach might involve defining a lot of functions that// look something like this/*** Returns true if hand is full-house*/function isFullHouse(cards) {var differentCards = [] ;for (var x=0; x < cards.length; x++) {differentCards[ valueOf( cards[x] ) ]++;}return (differentCards. indexOf(3) > 0) && (differentCards. indexOf(2) >0);}function compareTwoFullHouses (fullhouse1, fullhouse2) {...
  13. 13. Lets think about this...What do poker hands have in common?● 6 hands: Sets of Cards that are the same value.● 2 hands: Cards that have consecutive value● 2 hands: Cards that are all the same suit.Or● 8 hands: Counts of cards that share sameness on an attribute● 2 hands: Cards that have consecutive value
  14. 14. Coming up with an algorithm1. Take the hand. Extract relevantattribute. In this case, it means turn[ "3D", "3S", "6D", "2C", "2H"]into :[ 3, 3, 6, 2, 2]2. Find groups of cards. Turn itinto{3: 2, 6: 1, 2: 2} (meaning two threes, a six, and a pair of twos)3. Compare this to the hand definition.4. (For ties) Find a way to convey the second and third characteristics (in thiscase, that 6 of diamonds).
  15. 15. A functional approach[["Full House", followsPattern(cards, [3,2], cardValues)],["2 Pair", followsPattern(cards, [2,2,1], cardValues)],["Flush", followsPattern(cards, [5], cardSuits)],]var followsPattern = function(hand, expected, callback) {var values = FA(hand).map(callback); //Turn the input to an array of numbersvar groups = values.countBy(); //Get the counts of duplicatesif (! groups.values().hasAll(expected)) {return false; //This hand is NOT of the expected type, no match}var sets = groups.pairs(); //Turn {2: 3, 8: 2} into [[2, 3], [8, 2]] for examplesets = sets.sortBy(x[1] + "" + x[0]);//take advantage of alphabetical sort, sort by cardCount,// then card Value alpha in a tiereturn sets.pluck(0).join("");//pluck the first item, the cardValueAlpha};
  16. 16. Example Helper Function/*** return true if every value in needle is in this array,* at least as many times.*/FancyArray.prototype.hasAll = function(needle) {var summed = this.countBy().meld(FA(needle).countBy().mapObj( "a*-1"),"a+b");return summed.values().every( ">=0");};
  17. 17. So... Is it really better?Advantages:● Less Code● More Dry● Easier to keep track of● Easier to extend (saymake it work withholdem)● A little faster to writeDisadvantages:● Perhaps scary at first● A little harder towrap your brainaround● Could be off-puttingto collaborators whoknow nothing aboutthe notation.
  18. 18. YES.
  19. 19. Is this really functional programming?Isnt there more than this to functional programming?A challenge has been leveraged at underscore, namely by BrianLonsdorf. In his talk, "Underscore, Youre doing it wrong" in which hechallenged whether underscore really enabled functionalprogramming. In short he argued that underscores notation impededcurrying and composition.Its a fair criticism, and one that applies equally well to theecmascript 5 standard which put map in the array.prototype. Really,you cant map to another map eloquently or do other advancedfunctional programming things with the same grace. However, thisisnt a big issue for the vast majority of users.
  20. 20. How does it stack up?● Avoids State● Emphasizes use of functions● Avoids side-effects● Combines functions● Solves problems conceptuallyCall it whatever you want. The important thing is that youget the ability to write good, reusable, abstracted codeeasily. Dont optimize for an edge-case.
  21. 21. ThanksQuestions?Links: Libraries: