@nodeguy/generic
v3.0.2
Published
generic functions
Downloads
1,511
Maintainers
Readme
Generic Functions for JavaScript
It's time to bring something new old to JavaScript: generic functions!
Why?
Polymorphism in JavaScript is changing:
- ES 2015 brought an important new interface, the Iterable, which isn't a type so you can't use inheritance with it.
- After getting
Object.create
added to the language, Douglas Crockford doesn't use it any more. - Object Oriented Programming is dead. Yes sweetheart, it really is. Loosen your white knuckles and let it go. That's it, nice and easy. Exhale.
What are Generic Functions?
Generic functions were popularized in the Common Lisp Object System, published in 1988.
A generic function has a single signature (or interface) and multiple implementations, called methods. Unlike in OOP, the methods are specialized across all of the function arguments, not just the first one.
For example, the signature may be:
map(mapper, collection)
It may have different implementations based on the type of the collection:
const mapMethod = (callback, array) =>
array.map(callback);
const mapMethod = (callback, set) =>
new Set([...set].map(callback));
It may also have a method that takes a lookup table instead of a callback function:
const mapMethod = (table, array) =>
array.map((value) => table[value]);
In fact we could support lookup tables for every type of collection by adding a method that calls itself recursively like this:
const mapMethod = (table, collection) =>
map((value) => table[value], collection);
Usage
Here's how you could implement the above example using the library.
const assert = require(`@nodeguy/assert`);
const generic = require('@nodeguy/generic')
const _ = generic._;
const map = generic.function();
map.method([m => typeof m === "function", Array.isArray], (callback, array) =>
array.map(callback)
);
map.method(
[m => typeof m === "function", c => c instanceof Set],
(callback, set) => new Set([...set].map(callback))
);
map.method([m => typeof m === "object", _], (table, collection) =>
map(value => table[value], collection)
);
assert.deepEqual(map(Math.sqrt, [1, 4, 9]), [1, 2, 3]);
assert.deepEqual(map(Math.sqrt, new Set([1, 4, 9])), new Set([1, 2, 3]));
assert.deepEqual(map({ 1: 1, 4: 2, 9: 3 }, [1, 4, 9]), [1, 2, 3]);
assert.deepEqual(
map({ 1: 1, 4: 2, 9: 3 }, new Set([1, 4, 9])),
new Set([1, 2, 3])
);
See test/index.js
for more usage examples.
Installation
$ npm install @nodeguy/generic
Copyright
Copyright 2016 David Braun
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
these files except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
. Unless required by
applicable law or agreed to in writing, software distributed under the License
is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License.