Functional programming for MooTools
JavaScript
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
externals
FuncTools.js
index.html
license.txt
readme.textile

readme.textile

FuncTools

Overview

FuncTools is a small library of functional programming tools for MooTools.

Function.dispatch

Sometimes you want to define a single function that dispatches on arity, for example say you want to sum a range of numbers. You could loop over the array with an accumulator, but it’s much more fun to use Function.reduce.

var sum = Function.dispatch(
  function(a) { return a; },
  function(a, b) { return a + b.first(); }
);
sum.reduce($range(100));

Function.partial, Function.curry, Function.comp

It’s very useful to have an implementation of partial for currying arguments to a function in order, Function.partial helps here:

var partialFn = function(a, b) { return a * b }.partial(null, 3);
partialFn(4); // 12

However you don’t always have control of the argument order- i.e. using someone else’s library. If for some reason you need to supply arguments out of order you should use Function.curry:

var _ = Function._;
function abc(a, b, c) { return a + b + c; };
var curried = abc.curry(null, _, _, 3);
curried = curried(1);
curried(_, 2); // 6

Being able to compose functions is also very useful:

var MyClass = new Class({
  initialize: function(name) { this.name = name; },
  sayHello: function() {
    console.log("Hello from " + this.name)
  }
});
var ctorfn = function(name) { return new MyClass(name); };
["John", "Mary", "Bob"].map(Function.comp(ctorfn, Function.msg("sayHello")));

Function.decorate

Function decoration is also a very powerful technique. The Promises library uses this to great effect. We can memoize results for example. You would not want to run the following calculation without memoization:

var fib = function (n) {
  return n < 2 ? n : fib(n-1) + fib(n-2);
}.decorate(Function.memoize);
fib(100);

Preconditions & Postconditions

JavaScript is a fairly loose language – sometimes you just want to add a little bit of sanity. The Function.pre decorator can help here. You can specify the validating function for each argument:

var isEven = function(n) { return n % 2 == 0; };
var isOdd = $not(isEven);
var add = function(a, b) { return a + b; }.decorate(Function.pre([isEven, isOdd], true));
add(2, 3); // 5
add(2, 2); // throws exception

An example of a postcondition using Function.post:

var isSmith = Function.comp(Function.acc('last'), Function.eq('Smith'));

var fn = function(first, last) {
  return {first:first, last:last}; 
}.decorate(Function.post(isSmith, true));

fn("Bob", "Smith");
fn("Bob", "Howard"); // throws exception

Array.asFn, Hash.asFn

Often it’s very nice if you can treat an Array or a Hash as a function:

var address = {
   "city": "New York", 
   "state": "New York", 
   "zip": 100018, 
   "street": "350 5th Avenue",
   "building": "Empire State",
   "floor": 32
};
["building", "street", "city"].map($H(address).asFn()); // ["Empire State", "350 5th Avenue", "New York"]

var ary = ['cat', 'dog', 'bird', 'zebra', 'lion'];
[1, 3, 2].map(ary.asFn()); // ['dog', 'zebra', 'bird']

List of all functions

  • $identity
  • $callable
  • $range
  • $isnull
  • $notnull
  • $repeat
  • $get
  • Function.not
  • Function.eq
  • Function.iterate
  • Function.decorate
  • Function.comp
  • Function.partial
  • Function.curry
  • Function.memoize
  • Function.pre
  • Function.arglist
  • Function.dispatch
  • Function.reduce
  • Function.acc
  • Function.msg
  • Array.first
  • Array.rest
  • Array.drop
  • Array.tail
  • Array.head
  • Array.partition
  • Array.asFn
  • Hash.asFn
  • Hash.extract