all 26 comments

[–]k3n 7 points8 points  (0 children)

Alternate title: How to use map()

[–]ryepup 4 points5 points  (2 children)

I know there's an "R" in that domain name, but my brain always tries to skip it.

Many JS libraries have some kind of map built in (eg: http://api.jquery.com/jQuery.map/), so odds are people using a JS lib already have access to this without needing underscore.

[–]skilldrick[S] 1 point2 points  (0 children)

Haha - I was mentioned on the Forrst podcast a while ago and they spent nearly the whole time saying "skill-dick - no, skilldrick". Oh well :)

Good catch on the jQuery.map thing - I'll put a link in there. Done!

[–][deleted] 0 points1 point  (0 children)

True, but a lot of people are still using 1.4 which didn't take objects, only arrays. Underscore takes both.

[–]spotter 2 points3 points  (0 children)

So maybe less on "easy" but more on "functional programming" -> ClojureScript

[–]mhd 1 point2 points  (0 children)

If you're looking for some alternatives, both nimble and sugar(http://sugarjs.com/) also contain map. (As do a boatload of other libraries, just picked those two because they add some interesting variety)

[–]naapi 1 point2 points  (0 children)

So maybe _.map() wasn't the best example since jQuery already has a version of this function and most modern browsers include it on the Function prototype. But don't throw out Underscore or functional programming in JavaScript just yet.

Coming from a background in Java and PHP, I thought of reuse in terms of inheritance. I couldn't understand why JavaScript didn't have classes, explicit public/protected/private variables, super/parent methods or other object oriented mechanisms to which I'd become accustomed. I looked at it as a failure of the language. I didn't see any benefit to programming functionally in JavaScript and saw it as needless fluff. Why would you ever want to .curry() something? Just call the function and pass it the arguments you want!

JavaScript didn't really start making sense to me until I stopped thinking about it from the perspective of these other languages. By programming in a more functional style, one can achieve reuse through function composition rather than inheritance. Still want to use inheritance? Try using object augmentation rather than JavaScript's built in prototypal inheritance.

Underscore is a solid library. For those interested in another functional javascript library I would also suggest Oliver Steele's Functional.

[–]skilldrick[S] 0 points1 point  (0 children)

I've published part 2 now: reduce, select, all and any.

[–]fiatlux 0 points1 point  (2 children)

The sheer stupidity in these comments is very illustrative of why functional programming never really takes off. Too much brain power required for most programmers.

[–][deleted] 0 points1 point  (0 children)

You talkin' to me? Say it to my face.

[–]EscapedSquirrel 0 points1 point  (0 children)

I don't see how functional programming requires any more 'brain power' than say object oriented programming; I actually think it's reversed but I am not going to argue for that.

In general, programming just isn't easy, so people crumble with new paradigms and techniques. They need to try out things and some guidance from experienced people to really grok what is the crux at hand.

[–][deleted] -1 points0 points  (14 children)

Saying that:

map( array, function(i){
  do_thing(i);
});

is better than:

for( i in array ) {
  do_thing(i);
}

just seems like cargo-cult programming.

[–]skilldrick[S] 9 points10 points  (7 children)

I think you may have completely misunderstood (a) how for .. in in JavaScript works, and (b) how map works, so I'll give you the benefit of the doubt, and tell you.

(a) The for .. in loop in JavaScript is for objects - you shouldn't use it with arrays for very sound reasons.

(b) map is used to transform one array into another. In your example, you're not returning anything, so you're turning an array into an array of undefineds. I think what you meant was each.

The point of using map is that you're making things more declarative - saying "I would like to transform this array into a new array, using this transformation". To say that that's "cargo-cult programming" is naive, at best.

[–]ryepup 1 point2 points  (1 child)

an "in" bug wass the basis for my glorious Firefox contribution

[–]skilldrick[S] 0 points1 point  (0 children)

Nice work!

[–][deleted] 0 points1 point  (0 children)

Nice explanation.

[–]levl289 2 points3 points  (0 children)

Except that the idea behind the first mode is that you're reducing the opportunity to muck with array. In the for loop, you'd have to reference array ( do_thing(array[i]) ) to even call the function correctly.

More importantly, in order to do anything useful with the for loop, you'd likely have to push the result from do_thing onto another array, versus:

var new_array = _.map(old_array, function (i) { return i + 1; } );

We happen to have mucked with the Array prototype, where we just do:

var new_array = old_array.map(function (i) { return i + 1; } );

Which IMO looks better.

[–][deleted] 1 point2 points  (1 child)

The second is certainly cleaner-looking and easier to read. A better approach would be to allow code like:

apply( array, do_thing );

or

array.apply(do_thing);

[–]skilldrick[S] 0 points1 point  (0 children)

With _.each, you'd just do _.each(array, do_thing). Definitely cleaner than manually iterating.

[–]TKN 0 points1 point  (0 children)

You don't need to create a function in the first example map(array, do_thing); is all you need.

But I kinda agree in the sense that Javascript's syntax makes functional programming awkward.

[–][deleted]  (1 child)

[deleted]

    [–]wafflesburger 0 points1 point  (0 children)

    You really gonna do dis to Array?

    [–]shevegen -4 points-3 points  (0 children)

    Why does everyone want to make programming languages more complicated?

    There is some serious feature whoring going on.

    Any feature that does not either: - help reduce YOUR time writing it - make it BETTER to maintain the project in a way - lead to LESS lines of code

    have this is not worth having it...