Skip to content

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

License

Notifications You must be signed in to change notification settings

paldepind/functionize

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 

Repository files navigation

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)