A minimal library of functional operations

functools is a JavaScript library for functional programming.

Inspired by: Common Lisp, Clojure and Python. Tested on: Chrome, IE6 and Node. (See test/results.json for details)


Function Composition:

var compose = require("functools").compose;
compose(select, update, prettify, display)("body .messages");

Async Function Compositon:

function findFiles(pathcallback){  ... }
function readContents(filescallback){ ... }
function upload(filescallback){}
compose.async(findFiles, readContents, upload)('~/messages', function(erroruploadResult){

Async Juxtaposition:

function turkish(wordcallback){ /* some magic here */ }
function french(wordcallback){ /* some magic here */ }
function polish(wordcallback){ /* some magic here */ }
juxt.async({ 'tr': turkish, 'fr': french, 'pl': polish })("hello", function(error,  results){
  assert.equal(, "merhaba");
  assert.equal(, "bonjour");
  assert.equal(, "cześć");


var fn = require("functools");
var pickEvens = fn.curry(fn.filter)(function(num){ return num%2==0 });
pickEvens([3,1,4]) // returns [4] 
pickEvens([1,5,9,2,6,5]) // returns [2,6] 


$ npm install functools


$ wget



  • each.async
  • memoize
  • memoize.async


  • IE6, IE7 and IE8 bugfixes
  • better testing


Combine functions in a new one, passing the result of each function to next one, from left to right.

function cube(x){ return x*x*};
compose(Math.sqrt,cube)(4); // returns 8 

Asynchronous, continuation passing based version of compose function. Requires specified functions to call a callback function, passing an error object (if there is one) and the result to be carried.

function receiveMessage(messagecallback){ ... callback(); }
function findRelatedUser(messagecallback){ ... callback(null, user, message); }
function transmitMessage(usermessage){ ... callback(); }
var messageTransmission = compose.async(receiveMessage, findRelatedUser, transmitMessage);
messageTransmission({ msg:"Hello !", 'user': 3 }, function(errorresult){

Transform multiple-argument function into a chain of functions that return each other until all arguments are gathered.

function sum(x,y){ return x+y; }
var add3 = curry(sum, 3);
add3(14); // returns 17 
add3(20); // returns 23 

Call function once for each element in iterable.

each(function(el,ind,list){ console.assert( el == list[ind] ); }, [3, 1, 4]);

Call async function once for each element in iterable, and callback after iteration.

> function uploadFile(filenamecallback){
  console.log('Uploading ', filename);
> each.async(uploadFile, [ '/docs/intro', '/docs/body', '/docs/outro' ], function(error){
    console.log('Failed to upload files');
    throw error;
  console.log('All files has been uploaded successfully');
> Uploading /docs/intro
Uploading /docs/body
Uploading /docs/outro
All files has been uploaded successfully

Construct a new array from those elements of iterable for which function returns true.

filter(function(el,ind,list){ return el%2==0 }, [3, 1, 4]); // returns [4] 

Call async function once for each element in iterable, receiving a boolean parameter, and construct a new array of all the values for which function produces true

var users = [ 3, 5, 8, 13, 21 ]; // only user#3 and user#8 have permission in this example 
function hasPermission(userIdcallback){ ... callback(/* true or false */); }
filter.async(hasPermission, [3, 1, 4], function(permittedUsers){
  assert.equal(permittedUsers.length, /* ? */);

Take a set of functions, return a function that is the juxtaposition of those functions. The returned function takes a variable number of arguments and returns a list containing the result of applying each fn to the arguments.

function inc1(n){ return n+1 };
function inc2(n){ return n+2 };
function inc3(n){ return n+3 };
juxt(inc1, inc2, inc3)(314); // returns [315,316,317] 

Async implementation of juxt.

function turkish(wordcallback){ /* some magic here */ }
function french(wordcallback){ /* some magic here */ }
function polish(wordcallback){ /* some magic here */ }
juxt.async(turkish, french, polish)("hello", function(error,  results){
  assert.equal(results[0], "merhaba");
  assert.equal(results[1], "bonjour");
  assert.equal(results[2], "cześć");

Invoke function once for each element of iterable. Creates a new iterable containing the values returned by the function.

function square(n){
  return n*n;
map(square, [3,1,4,1,5,9]); // returns [9,1,16,1,25,81] 

Objects can be passed as well;

var dict = { 'en':'hello', 'tr': 'merhaba', 'fr':'bonjour' };
function capitalize(str){
  return str.charAt(0).toUpperCase() + str.slice(1);
map(capitalize, dict); // returns { 'en':'Hello', 'tr':'Merhaba', 'fr':'Bonjour' } 

Apply async function to every item of iterable, receiving a callback function which takes error (if there is) and replacement parameters.

function readFile(idcallback){ ... callback(undefined, data); }
map.async(readFile, ['./foo/bar', './foo/qux', './corge'], function(errorfiles){
  if(error) throw error;
  console.log(files[0]); // will put the content of ./foo/bar 

Return a memoized version of function. hasher is optional.

> function myfunc(n){
    console.log("doing some work");
    return n + 10;
> var myfuncMemo = memoize(myfunc);
> myfuncMemo(1);
"doing some work"
> myfuncMemo(1);
> myfuncMemo(20);
"doing some work"
> myfuncMemo(20);

Memoize given async function if it doesn't produce any error.

> function readFile(){ console.log('doing some work'); ... callback(undefined, buffer); }
> var readFileMemo = memoize.async(readFile);
> readFileMemo('/docs/readme', function(errorcontent){
"doing some work"
> "This is the Readme file"
> readFileMemo('/docs/readme', function(errorcontent){
"This is the Readme file"

Return a new function which will call function with the gathered arguments.

function testPartial(){
  var args = reduce(function(x,y){ x+""+},arguments);
partial(testPartial, [3,14], 3.14159)(1,5,9);

The example code above will output:

this: 3.14159
args: 3,14,1,5,9

<a name="reduce />

Apply function cumulatively to the items of iterable, as to reduce the iterable to a single value

reduce(function(x,y){ return x*}, [3,1,4]); // returns 12 

Async implementation of reduce.

var users = [2, 3, 5, 8, 13];
function usernames(accumuserId){ ... callback(undefined, accum + '' + username); }
reduce.async(usernames, users, function(errorresult){
  if(error) throw error;
  console.log(result); // foo, bar, qux ... 


$ npm test

Run make test command to publish the tests on localhost:1314. Visit the URL using the browser on which you want to run the tests. Stop the server (Ctrl+C) when you're done with testing.

To see the summary of results;

$ make test do=verify
Not Tested: firefox, ie8, ie7
Passed: ie6, webkit
Revision: 1.3.0
Results Source: test/results.json
Config: test/config.json