Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Fun.js – Just a sketch (fogus.me)
29 points by DanielRibeiro on June 6, 2013 | hide | past | favorite | 21 comments


A lot of these examples are wrong...

    function double(n) { return 2*n; }
    map(double, [1,2,3])
    //=> [1, 4, 9]
should be => [2, 4, 6]

    function greaterThan(l, r) {
      return l > r;
    }
    greaterThan(5, 100);
    //=> true
should be => false

    maybeGT(5)(10000000);
    //=> false
Based on your earlier declaration of greaterThan this result is actually correct. The curried application ordering is also correct and flip is unneeded.

    schonfinkel(function(a1,a2) {return [a1,a2];})(1)(2);
    //=> [1, 2]
I would proofread the rest but I am about to be late for class! =O

Edit: since i'm going to complain I might as well say something nice as well. I did like this article example correctness aside, and I hadn't seen that implementation of pipeline before! Much awesome. =)


Actually, I think the original intent regarding greater than was:

    greaterThan(100, 5);
    //=> true
That is, l is greater than r, and to then properly curry the arguments do need to be flipped such that maybeGT(5) results in a function that returns whether the argument is greater than 5.


Exactly right. We like to be able to do something like:

    var gtThreshold = gt(100);
And then:

    filter(gtThreshold, array);
This is nicely fluent I would say.


Someone has already addressed the maybeGT case, but you were right about the double problem. I had originally made it a squaring function, but for some dumb reason decided to make it a doubler instead just before submitting. There is a lesson in there about last moment changes. ;-)


Some questions from JS novice:

Why map isn't implemented:

    function map(fun, coll) {
      if (exists(coll)) return _map(fun)(coll);
      return _map(fun);
    }
Why use arguments when you can name your parameter in declaration?

And why _map is defined in global scope? Shouldn't it be better defined inside map function? What are up/downsides in performance for this move?


Very interesting post but I'm having trouble with one thing. pipeline(5) returns 5. When I try to follow that path, I get to this: reduce(function(l,r) { return r(l); }, seed, funs) with seed=5 and funs=[] (an empty array). How does that reduction evaluate to 5? In other words, what is "r(l)" when l=5 and r=the first member of an empty array?


In reduce the accumulator starts as the seed and is changed in the forEach for each elem. Since there are so elems (funs) the accumulator never changes and returns as the value of seed (5).


Of course. Shoulda seen that. ;) forEach on an empty collection returns immediately. Thanks.


Sorry to nitpick, but I got hung up right at the beginning with his "truthy" function.

It returns true on values such as NaN, zero, or an empty string. I don't think I'm alone in considering those to be "falsy" values, for example:

http://www.sitepoint.com/javascript-truthy-falsy/


Technically the are JS falsey, but I choose not to treat them that way. I rarely want to treat the result of a calculation as a boolean condition. However, I often want to know if a calculation isNaN or isEmpty. Just because something is falsey doesn't mean it should be treated that way universally.


Right on, I get that, but truthy(NaN) and truthy(5) both return true, so you still don't know if the calculation isNaN.

Btw, I should have said first: I love the article in general and it's great to see these techniques becoming more mainstream in javascript. Thank you!


I would probably structure the problem like this:

    var ans = someCalculation(x,y);
    
    if (truthy(ans) && !isNaN(ans))
      //do something
    else
      //do something else
The point being I like to dispatch conditions on boolean results of certain properties of my results rather than the result directly. It helps me to keep my sanity.

Thanks for the kind words BTW. :-)


It's probably as common to have them falsy as truthy; notably, they're truthy in Ruby.


Just a note - forEach doesn't work in IE8. I wonder at what point can we stop caring about that?


there are shims - the MDN one works well, or you can download this library to shim the whole of ES5 https://github.com/kriskowal/es5-shim (other libraries are availble)

Focusing on modern browsers and shimming the old ones is the way to go, IMHO


What would you say are the skills required to fully understand this?


Possibly not too high. Try using map, filter, and reduce on some example problems and you'll pick it up fairly quickly. Project Euler makes for decent fodder. When you've successfully managed to apply them then try rewriting the functions (delete the implementation you are using - such as the library above - and rewrite it from scratch).


I wouldn't recommend Project Euler - it's math-based and that would be a roundabout way of learning anything else but math.

Here's my recommendation: http://www.haskell.org/haskellwiki/H-99:_Ninety-Nine_Haskell...


It's a pretty fast paced intro to a lot of functional programming concepts. You can read a guide like learnyouahaskell.com, which will take you on a gentler ride.


Thanks I tried haskell a few ties but never got the real life application to that.


Good read, nice intro into functional programming. Thanks!




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: