Skip to content

Instantly share code, notes, and snippets.

@CrossEye
Forked from AutoSponge/tco.md
Last active December 16, 2015 14:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CrossEye/5448726 to your computer and use it in GitHub Desktop.
Save CrossEye/5448726 to your computer and use it in GitHub Desktop.
//don't use native bind... it's too slow
function recur(fn) {
return function () {
var bounce = fn.apply(this, arguments);
while (bounce.call) {
bounce = bounce();
}
return bounce;
};
}
function bind(fn, receiver) {
return function () {
var args = arguments;
return function () {
return fn.apply(receiver || this, args);
};
};
}
var sum = bind(function (x, y) {
return y > 0 ? sum(x + 1, y - 1) :
y < 0 ? sum(x - 1, y + 1) :
x + this.test;
}, {test: "done"});
var sum1 = recur(sum);
sum1(1, 50000);
//a cleaner approach?
function recur(fn) {
return function () {
var bounce = fn.apply(this, arguments);
while (bounce.call) {
bounce = bounce();
}
return bounce;
};
}
var sum = Function.call.bind.bind(function (x, y) {
return y > 0 ? sum(x + 1, y - 1) :
y < 0 ? sum(x - 1, y + 1) :
x;
}, null);
var sum1 = recur(sum);
sum1(1, 50000);
function recur(fn) {
return function () {
var bounce = fn.apply(this, arguments);
while (bounce.call) {
bounce = bounce();
}
return bounce;
};
}
var sum1 = recur(function sum(x, y) {
return function() {
return y > 0 ? sum(x + 1, y - 1) :
y < 0 ? sum(x - 1, y + 1) :
x;
};
});
sum1(1,50000);
// This works properly
var recur = function(fn) {
return function () {
var bounce = fn.apply(this, arguments);
while (typeof bounce === "function") {
bounce = bounce();
}
return bounce;
};
};
var _$ = function(name, fn) {
var lines = ("" + fn).split(/\r?\n/), first = (lines.pop(), lines.shift()),
body = lines.join("\n "), match = first.match(/\(([^)]*)\)/), args = match && match[1] || "";
var newFnStr = ("" + function name(args) {
return function () {
return 'body';
};
}).replace("name", name).replace("args", args).replace("return 'body';", body).split("\n ").join("\n");
return recur(Function("return " + newFnStr)());
};
var sum = _$("sum", function(x, y) {
return y > 0 ? sum(x + 1, y - 1) :
y < 0 ? sum(x - 1, y + 1) :
x;
});
console.log(sum(1, 5000)); // 5001
console.log(sum(1, 50000)); // 50001
console.log(sum(1, 500000)); // 500001
console.log(sum(1, 5000000)); // 5000001
// But the function constructor doesn't have access to local functions.
var lib = (function() {
var recur = function(fn) {
return function () {
var bounce = fn.apply(this, arguments);
while (typeof bounce === "function") {
bounce = bounce();
}
return bounce;
};
};
var _$ = function(name, fn) {
var lines = ("" + fn).split(/\r?\n/), first = (lines.pop(), lines.shift()),
body = lines.join("\n "), match = first.match(/\(([^)]*)\)/), args = match && match[1] || "";
var newFnStr = ("" + function name(args) {
return function () {
return 'body';
};
}).replace("name", name).replace("args", args).replace("return 'body';", body).split("\n ").join("\n");
return recur(Function("return " + newFnStr)());
};
var inc = function(n) {return n + 1;};
var dec = function(n) {return n - 1;};
var sum = _$("sum", function(x, y) {
return y > 0 ? sum(inc(x), dec(y)) :
y < 0 ? sum(dec(x), inc(y)) :
x;
});
return {
sum: sum
};
}());
console.log(lib.sum(1, 5000)); // Uncaught ReferenceError: inc is not defined
// This does work, at the expense of requiring functions to use the namespaced access to otherwise local functions
var lib = (function() {
var E = {};
var recur = function(fn) {
return function () {
var bounce = fn.apply(this, arguments);
while (typeof bounce === "function") {
bounce = bounce();
}
return bounce;
};
};
var _$ = function(name, fn) {
var lines = ("" + fn).split(/\r?\n/), first = (lines.pop(), lines.shift()),
body = lines.join("\n "), match = first.match(/\(([^)]*)\)/), args = match && match[1] || "";
var newFnStr = ("" + function name(args) {
return function () {
return 'body';
};
}).replace("name", name).replace("args", args).replace("return 'body';", body).split("\n ").join("\n");
return recur(Function("E", "return " + newFnStr)(E));
};
E.inc = function(n) {return n + 1;};
E.dec = function(n) {return n - 1;};
var sum = E.sum = _$("sum", function(x, y) {
return y > 0 ? sum(E.inc(x), E.dec(y)) :
y < 0 ? sum(E.dec(x), E.inc(y)) :
x;
});
return E;
}());
console.log(lib.sum(1, 5000)); // 5001
console.log(lib.sum(1, 50000)); // 50001
console.log(lib.sum(1, 500000)); // 500001
console.log(lib.sum(1, 5000000)); // 5000001
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment