npm install @nodeguy/genericIt's time to bring something new old to JavaScript: generic functions!
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.
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:
``JavaScript`
map(mapper, collection)
It may have different implementations based on the type of the collection:
`JavaScript
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:
`JavaScript`
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:
`JavaScript`
const mapMethod = (table, collection) =>
map((value) => table[value], collection);
Here's how you could implement the above example using the library.
`JavaScript@nodeguy/assert
const assert = require();
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.
$ npm install @nodeguy/generic
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.