Pattern matching for JavaScript.
JavaScript
Switch branches/tags
Nothing to show
Latest commit bc4d9e7 Oct 24, 2011 @Gozala Modify bugs uri format.
Permalink
Failed to load latest commit information.
tests
History.md
Readme.md
core.js
package.json

Readme.md

dispatcher

Pattern matching for JavaScript.

Library can be used to implement functions supporting range of different dispatchers, in a declarative manner avoiding mess of conditional blocks & manual argument validations. While primarily this aims to improve code readability and maintainability, in some cases this can be useful to optimize specific, hot code paths.

Examples

var dispatcher = require('dispatcher/core').dispatcher

function number(value) {
  if (typeof(value) !== 'number') throw Error('Not a number')
  return value
}

var sum = dispatcher({ doc: "sums given numbers", added: "0.1.0" },
  // If no arguments are passed then 0.
  [], function() { return 0 },
  // If only one argument is passed return back.
  [ number ], function(x) { return x },
  // Optimize two argument case.
  [ number, number ], function(x, y) { return x + y },
  // If more then two then take all the args starting from second as
  // rest array.
  [ number, [] ], function (x, rest) {
    called.number_rest ++;
    return rest.reduce(function(x, y) {
      return x + y
    }, x)
  })


sum()               // => 0
sum(1)              // => 1
sum(2, 3)           // => 5
sum(2, 5, 17, 1)    // => 25
sum([ 4 ])          // TypeError -> Unsupported dispatcher


// Define guards
function string(value) {
  if (typeof(value) !== 'string') throw Error('Not a string')
  return value
}
function lambda(value) {
  if (typeof(value) !== 'function') throw Error('Not a function')
  return value
}
function array(value) {
  if (!Array.isArray(value)) throw Error('Not an array')
  return value
}
function object(value) {
  if (!value || typeof(value) !== 'object') throw new Error('Not an object')
  return value
}

var map = dispatcher(
  // Function that operates on strings
  [ lambda, string ], function(lambda, string) {
    var index = -1, length = string.length, chars = []
    while (++index < length) chars[index] = lambda(string[index])
    return chars.join('')
  },
  // Function that operates on arrays
  [ lambda, array ], function(lambda, array) {
    var index = -1, length = array.length, elements = []
    while (++index < length) elements[index] = lambda(array[index])
    return elements
  },
  // Function that operates on objects
  [ lambda, object ], function(lambda, object) {
    var pair, value = Object.create(Object.getPrototypeOf(object))
    for (var key in object) {
      pair = lambda(key, object[key])
      value[pair[0]] = pair[1]
    }
    return value
  },
  // Function that operates on everything else
  [ lambda, , ], function(lambda, value) {
    return lambda(value)
  })


map(function($) { return $.toUpperCase() }, 'hello world')
// => 'HELLO WORLD'

map(function($) { return $ * 2 }, [ 1, 2, 3 ])
// => [ 2, 4, 6 ]

map(function(k, v) { return [ '@' + k, v + '!' ] }, { foo: 1, bar: 'baz' })
// => { '@foo': '1!', '@bar': 'baz!' }

map(function($) { return $ + 1 }, 6)
// => 7

map(function($) { return $ + '!' }, 'hello', 'world')
// TypeError -> Unsupported dispatcher

Install

npm install dispatcher