Successfully reported this slideshow.

More Related Content

Related Books

Free with a 14 day trial from Scribd

See all

Related Audiobooks

Free with a 14 day trial from Scribd

See all

Fancy talk

  1. 1. Introducing ƒancy Writing functional javascript that can hit production
  2. 2. Write performant, stable, readable, debuggable, and production worthy code quickly. In short, to make life easier. I won't invoke complex vocabulary, math, and theory; I don't 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 collection d. And some other functions I felt were needed (chunk) FancyArray([1,2,3]).sortBy("%2"); >>> [2, 1, 3] a b c
  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 a FancyArray, thus allowing chaining. When one of underscore's functions would have returned an object, it instead returns a FancyObject. However, unlike underscore's .chain method, these one-off objects act very much like normal arrays or objects.
  6. 6. And- Also, any function that takes another function as an argument (like map) can take a string to represent that function as devised by Oliver Steele FancyArray([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 FancyArray Though you may not see from the chrome console output, this is still a FancyArray Functional.js style function
  8. 8. How does that make my life easier? You can read your code left-to-right, like english It's now shorter than declarative, with less ugly nesting. No pollution of public scope or prototypes. var samplePeople = { ... }; // fancy - This is prettier FO(samplePeople).values().sortBy( ".age").pluck("name"); // plain underscore - Than that _.chain(samplePeople).values().sortBy( function(p) { return p.age; }).pluck( "name").value();
  9. 9. Let's 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 Flush 2. 4 of a kind 3. Full-House 4. Flush 5. Straight 6. 3 of a kind 7. 2 Pair 8. 1 Pair 9. High card 2nd - Card Values How high are the cards used to make up the hand? 3rd - Card Values How high are the remaining cards in the hand?
  11. 11. Example: Full House: 3 Of 1 value 2 Of another Value Beats lower ranking hands (like a straight). Loses to higher-ranking hands. (Straight flush). If two full houses happen, compare the sets of 3, whichever has the higher value wins. If those are equal, compare the pairs of two, whichever has the higher 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. Let's 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 algorithm 1. Take the hand. Extract relevant attribute. In this case, it means turn [ "3D", "3S", "6D", "2C", "2H"] into : [ 3, 3, 6, 2, 2] 2. Find groups of cards. Turn it into {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 this case, 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 numbers var groups = values.countBy(); //Get the counts of duplicates if (! 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 example sets = sets.sortBy('x[1] + "" + x[0]'); //take advantage of alphabetical sort, sort by cardCount, // then card Value alpha in a tie return 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 (say make it work with hold'em) ● A little faster to write Disadvantages: ● Perhaps scary at first ● A little harder to wrap your brain around ● Could be off-putting to collaborators who know nothing about the notation.
  18. 18. YES.
  19. 19. Is this really functional programming? Isn't there more than this to functional programming? A challenge has been leveraged at underscore, namely by Brian Lonsdorf. In his talk, "Underscore, You're doing it wrong" in which he challenged whether underscore really enabled functional programming. In short he argued that underscore's notation impeded currying and composition. It's a fair criticism, and one that applies equally well to the ecmascript 5 standard which put map in the array.prototype. Really, you can't map to another map eloquently or do other advanced functional programming things with the same grace. However, this isn't 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 conceptually Call it whatever you want. The important thing is that you get the ability to write good, reusable, abstracted code easily. Don't optimize for an edge-case.
  21. 21. Thanks Questions? Links: https://github.com/anfurny/fancy http://blog.alexrohde.com/ Source Libraries: http://underscorejs.org/ http://osteele.com/sources/javascript/functional/

×