
Underscore.js: Annotated Source Code - shawndumas
http://documentcloud.github.com/underscore/docs/underscore.html
======
helium
I wish more open source libraries had this. This seems to be a trend in the
javascript ecosystems. Coffeescript also has this.
<http://jashkenas.github.com/coffee-script/>

~~~
shawndumas
Same author; the venerable Jeremy Ashkenas[1].

And yes; quality is fractal.

\----

[1]: <http://github.com/jashkenas>

------
luigi
Next to jQuery, Underscore is my most-used JS library. Makes scripting client-
side behavior so much more pleasant.

~~~
steadicat
I tweeted this yesterday:

Why does Underscore.js get the order of arguments wrong? There’s a reason why
it’s map(fn, l), not map(l, fn). And the reason is currying.

I find that very annoying for the kind of functional programming I tend to do.
For that reason alone I started looking at Wu.js instead.

Am I missing something?

~~~
jashkenas
Order of arguments shouldn't be a fundamental problem for currying --
libraries like Functional.js allow you to curry from the left, or to curry
from the right, as you desire.

However, having higher-order functions in JavaScript take their function
argument in the final position is an extremely common and important pattern in
JavaScript. Most libraries prefer this:

    
    
        call(arg, arg, function() {
          ...
        });
    

Instead of this (which hides relevant arguments far away from the actual call
site):

    
    
        call(function() {
          ...
        }, arg, arg);

~~~
steadicat
That's a good point. However, I find it funny that you should mention another
functional library as a way around the issue. Doesn't that defeat the purpose
of Underscore?

I have a feeling that either the authors of Underscore don't fully get
functional programming, or I don't. Of course, the latter is much more likely,
that's why I'm looking for someone to set me straight.

~~~
jashkenas
Full disclosure: I'm the author.

Depending on your definition, nothing in JavaScript is "fully functional
programming", because then it would have to be side-effect-free, and
JavaScript is very much not that language.

Calling them "functional helpers" is mostly a way of distinguishing the style
in which you use them, as opposed to the object-oriented versions of the same
helper functions, which can be found in libraries like Prototype.js. The idea
here being that you can use them in a functional style without having to
extend native objects.

As I mentioned above, calling "map" with the iterator as the final argument
isn't a limitation here -- it's a feature. There aren't many (any) situations
I've ever seen in real-world JS where you'd want to curry together a list of
iterators, and then map them together across the array, all at once. And if
you do want to do such a thing, you can accomplish it either like this:

    
    
        _.map(list, function(item) {
          return convert1(convert2(convert3(item)));
        });
    

Or, if you want to get fancy, take a look at "compose":

<http://documentcloud.github.com/underscore/#compose>

    
    
        _.map(list, _.compose(convert1, convert2, convert3));

------
lux
I'd love to know if there's a lib for generating annotations like this from
source comments. I've always loved docs tha include the code for reference,
helps to see what's actually going on :)

~~~
sant0sk1
<http://github.com/jashkenas/docco>

<http://github.com/rtomayko/rocco>

<http://github.com/rtomayko/shocco>

~~~
jashkenas
Docco is CoffeeScript/JavaScript, Rocco is Ruby, Shocco is Shell, and there's
one more (that I know of) ... Pycco for Python:

<http://github.com/fitzgen/pycco>

And a first cousin, once removed: Dox (JavaScript):

<http://visionmedia.github.com/dox/>

~~~
jacobolus
Dox seems to just be explicitly marked documentation, not every comment.

Pycco claims to support Python, Ruby, JavaScript, CoffeeScript, Scheme, and
Lua.

------
moron4hire
This is just a style comment, but given JavaScript's open class prototypes and
expando objects, I generally prefer to write these methods as new members on
their natural classes. For example, the RegEx escape method would be on the
RegEx class itself, rather than being a stand alone function.

Other than that, this is an incredibly useful set of functions that any
JavaScript developer should have in their toolkit.

~~~
rtp
You mean like putting the methods into the native classes' prototypes? That's
a bad idea. The reason why it is a bad idea is that you cannot extend a
prototype only within a scope, i.e if you change the prototype, it'll be
changed regardless of whether it'll break another library, or that another
library replaces your methods and thus render your library broken. This opens
up the risk that you'll end up with bugs that are hard to trace to their
source.

