paldepind / functionize

A library which aids in making any JavaScript library more functional.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

functionize

A collection of functions which aids in making non-functional libraries functional.

Note: functionize is currently in an early stage. If you have ideas or a different vision about how such a library should be, please share them.

Background

functionize is based on the idea that an ideal function should usually satisfy the following requirements.

  • Be curried, i.e. return a partial applied version of itself when called with too few arguments.
  • Have a fixed arity (i.e take a constant amount of arguments).
  • Take any data it operates on as its last argument. This discourages the use of functions that operate on a bound context (this).

Unfortunately the above ideas are not shared by the majority of the JavaScript community thus the need for functionize.

Goals

  • Make it easy and concise to convert any library into one that adheres to the above criteria as much as possible.
  • Facilitate sharing and reuse of such library conversions.
  • Take the conversion burden of other functional libraries, making them more focused in scope.

How it works

functionize tries to be as unfancy as possible. And instead of writing actual configuration you pass the library to be transformed through a series of composed functions. This achieves simplicity and flexibility.

Examples

Converting String

This is a simple conversion of the standard String methods in JavaScript

var converter = fz.pipe([
  fz.omit(['anchor', 'big', 'blink', 'bold', 'fixed', 'fontcolor',
           'fontsize', 'italics', 'link', 'small', 'strike', 'sub', 'sup']),
  fz.methods, fz.map(fz.fnInvoker),
  fz.mapTo({
    slice: {sliceFrom: [fz.apply(fz._, [fz._, undefined])],
            sliceTo: [fz.apply(fz._, [undefined])]},
    concat: {concat: [fz.rearg([1, 0])]},
    toUpperCase: {uppercase: []},
  }),
]);
var S = converter(String.prototype);

It can be used like this

// Slicing
var sliceFrom6 = S.slice(6); // functions are curried
sliceFrom6(8, 'abcdefghijklm'); // 'gh'
S.sliceTo(4, 'abcdefghijklm'); // 'abcd'

S.trim(' horse  '); // 'horse'
S.uppercase('foobar'); // 'FOOBAR'
S.concat('foo', 'bar'); // 'foobar'

Converting Array

var converter = fz.pipe([
  fz.methods, fz.map(fz.fnInvoker),
  fz.to({
    sortBy: [fz.prop('sort')],
    sort: [fz.prop('sort'), fz.apply(fz._, [undefined])],
  }),
]);
var A = converter(Array.prototype);

It can be used like this

var a = [3, 8, 4];
A.sort(a); // [3, 4, 8]
var ns = [3, 8, 4];
var square = A.map(function(x) { return x*x; }); // [9, 64, 16]

API

For better documentation see the source and/or the tests.

curryN(arity, fn)

Return a curried function with arity arity that calls fn when it has recieved all its arguments.

map(fn, obj)

Maps a function over an object(not an array). The mapper function recieves both the object value and key.

filter(fn, obj)

Maps a function over an object and returns an object with only the keys whose properties satisfies the predicate function.

arity(fn)

Returns the arity of the passed function.

invoker(arity, methodName)

Returns a functions that applies the named method to an object.

fnInvoker(fn, methodName)

Like invoker, but extracts its arity from fn.

methods(obj)

Returns an object with all the objects on obj.

mapFields(properties, fn, obj)

For each property in propeties it takes that property from obj passes it through fn and returns an object with the keys overwritten by the result of fn.

var obj = {a: 1, bunch: 2, of: 3, properties: 4};
var newObj = fz.mapFields(['bunch', 'of'], function(x) { return x + 3; }, obj);
newObj; // {a: 1, bunch: 5, of: 3, properties: 7}

rearg(newOrder, fn)

Rearranges the arguments of a function.

function f(a, b, c) {
  return a + b + c;
}
var g = fz.rearg([2, 0, 1], fn);
g('a', 'b', 'c'); // 'bca'

flip(fn)

Returns a function equivalent to fn but with the order of its two first arguments reversed.

Note: flip is excactly the same as rearg([1, 0]). Its removal is considered.

pipe(fns)

Compose, left to right. I.e: pipe(f, g, h)(x) is the same as h(g(f(x))).

apply(fn, arr)

Calls fn with the arguments specified in arr.

omit(keys, obj)

Returns obj without the keys mentioned in keys.

About

A library which aids in making any JavaScript library more functional.

License:MIT License


Languages

Language:JavaScript 100.0%