Skip to content

Latest commit

 

History

History
140 lines (109 loc) · 3.58 KB

readme.textile

File metadata and controls

140 lines (109 loc) · 3.58 KB

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