Skip to content

Instantly share code, notes, and snippets.

@gliese1337
Last active January 12, 2018 02:51
Show Gist options
  • Save gliese1337/2d55a6770d39c6138dca41fc867636f6 to your computer and use it in GitHub Desktop.
Save gliese1337/2d55a6770d39c6138dca41fc867636f6 to your computer and use it in GitHub Desktop.
A JavaScript multimethod library.
const clauses = new Symbol();
function Multimethod(){
const self = !!new.target ? this : Object.create(Multimethod.prototype);
self[clauses] = [];
return new Proxy(self,{
apply: function(target, thisArg, args){
let curImpl = () => throw new Error("No Matching Implementation");
let curLen = -1;
for(const { thisPredicate, predicates, impl } of self[clauses]){
if(predicates.length > curLen && (thisPredicate || () => true)(thisArg) && predicates.every((p, i) => {
const v = args[i];
try { return !p || v instanceof p || p(v); }
catch(_){ return false; }
})){
curImpl = impl;
curLen = predicates.length;
}
}
curImpl.apply(thisArgs, args);
}
});
}
Multimethod.prototype.clause = function(thisPredicate, predicates, impl){
this[clauses].push({ thisPredicate, predicates, impl });
};
module.exports = Multimethod;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment