Looks like a very handy bunch of code, but I can't say I like the "_" part of it.
One of the neatest things about jQuery is the way all of the jQuery functionality lives in the "jQuery" namespace, with $ just set up as a convenient shortcut. If you don't want the $ in your global namespace (but still want it in your own code) you can do this:
jQuery.noConflict();
jQuery(function($) {
// Code that uses the $ shortcut
}
Feature request for underscore: something similar. If I'm already using the _ for something I'd like to still be able to use the underscore library, but bound to a different symbol.
Underscore.noConflict();
Underscore(function(_) {
// My code that uses _
}
Quick Summary:
Underscore provides all the functional programming goodies that you would expect with Prototype.js or Ruby, but without extending any core javascript objects, so it can fit hand-in-hand with jQuery. In Javascript 1.6 compliant browsers, it delegates to the native versions of functions, so you can have your "map()" and run run it at native speed where available. The production version compresses to 4k, so there's not much overhead in adding it to a page.
Awesome stuff but binding your library to _ (underscore) is unfortunate. That character is traditionally reserved for the gettext / i18n / gimme-a-string-in-human-language-X function.
Or if you're into MooTools checkout http://github.com/ShiftSpace/functools for decorators, pre & postconditions, memoize, arrays and hashes as functions, currying any function parameter, function composition, arity dispatch, etc.
function example() {
var remotes = ['a', 'b', 'c', 'd', 'e', 'f'];
var result = "";
while(remotev = remotes.shift()) {
result = add(result, get(remotev)); // get is an async request! ;)
}
show(result); // -> console.logs "abcdef"
}
No callbacks, your code looks like (and _is_) regular javascript even though this triggers 6 requests. AJAX callback code is the new spaghetti and this is an antidote.
You might also be interested in http://osteele.com/sources/javascript/concurrent/ for another approach to this. [later, after reading more:] Actually, Promises looks much more complete and useful.
Thanks for this! I recall reading over your article, http://osteele.com/sources/javascript/functional/, back in the day and being completely baffled and intrigued. These days I've been hacking with Clojure and wanting to bring some of that FP sanity back to my daily work ;)
edit: by that I mean it's useful without jQuery. It's already been added to Narwhal server-side JS package manager: http://github.com/kriskowal/underscore
Underscore isn't tied to jQuery either. It just complements it nicely.
Oliver Steele's Functional is a great library too, and bits of Underscore were inspired by it. The main difference between the parts they have in common is that Functional.js extends the core Function prototype, while Underscore avoids altering any core objects.
Thanks! You can also feel free to mine http://github.com/osteele/collections-js, which is a version with just the collection functions (but still modifies built-in objects, so may not be to other people's taste), that I've been using in conjunction with jQuery. I haven't finished looking over your library, so I don't know if there's anything in there that would still be useful to you. There's a set of unit tests, which might be.
I eventually found that I was accumulating so many string functions that, in a version of this for OpenLaszlo here http://github.com/osteele/lzosutils, I broke them into a separate file.
Collections-js looks like a nice split -- I might end up nabbing a few more things out of there. Maybe some of the unit tests too, although, FYI, your Functional.js page has shown "Documentation Failed to Load" for me for the last few days (on Webkit).
One thing that it would be nice to agree on is the standard names for some of these things under Javascript. What should reduce be called? Inject? Foldl? I've followed the Prototype/Ruby naming conventions, but it might make sense to provide all of the commonly-used aliases -- especially when you're not extending core objects, and don't need to worry about cluttering them up. What do you think? Does the same function under 5 different names run as sweet?
Not inject. Inject was borrowed from smalltalk's #inject:into, but dropped the "into" and just ended up being unintuitive for many people. Ruby 1.8.7 and 1.9 now have #reduce, so I'd say that's the way to go. No reason to use foldl unless you're going to also have a foldr.
I spend most of my day as a Ruby developer, but when I'm doing frontend work, the thing I miss most in Javascript is Ruby's incredibly simple, powerful list operations. While most of these have existed in some form for awhile now, I've never seen such a comprehensive implementation in just 5.2kb (minified) of very clean, simple, well-commented code.
This is probably going in every project I work on from here on out. Thanks for putting all of this together.
I know I've implemented a fair few of those functions on a more ad hoc basis in number of projects. So it's really nice to see someone putting it all together in a simple package. I'll certainly be having a closer look at the source code and trying it out on my current project.
This will go great with jQuery. I've missed some of these helpers when moving to jQuery from Prototype. I felt much better about not polluting globals after the switch, but this look like it's a nice half-way solution between Prototype's style and nothing at all.
0.3.0 is out, with a bunch of fine-tuning loop optimizations provided by Dmitry Baranovskiy, and CommonJS/Narwhal support, for those of you who use JavaScript on the server as well as the client.
Cool stuff. The only thing that keeps me from writing in a more functional style is the fact that no current browser implementations perform tail recursion optimization.
Funny, that's precisely what we're doing at DocumentCloud -- Base.js for OOP / jQuery.js for DOM and Ajax / Underscore.js for functional...
Part of the idea is to make it easy to add functional utility methods to an existing project without making any other assumptions. You can use it with whatever OO scheme you've got cooked up, any Ajax library, and any DOM-manipulation framework.
What advantages would a "mix'n'match" approach like this have over something unified like Prototype (which, as far as I can tell, includes implementations of all the parts you are using)?
I have found Prototype much better for a "web-app" framework - I can build up complex controls and effects with the "OOP"/Inheritance framework, and I have access to all the functional tools I'm used to from Ruby.
JQuery, on the other hand, has always felt "lighter" - really great for a quick Carousel control on a marketing site, or a pop-up effect or something like that, but it quickly turns into spaghetti with anything more complex.
I'd be interested in other people's views on this split, especially people with experience using a whole toolset like yourself.
One of the neatest things about jQuery is the way all of the jQuery functionality lives in the "jQuery" namespace, with $ just set up as a convenient shortcut. If you don't want the $ in your global namespace (but still want it in your own code) you can do this:
Feature request for underscore: something similar. If I'm already using the _ for something I'd like to still be able to use the underscore library, but bound to a different symbol.