-
-
Save candyapplecorn/733e740a0dc3b2ba55b72405b884a7fe to your computer and use it in GitHub Desktop.
Lazy evaluation in JavaScript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function delay(expressionAsFunction) { | |
var result; | |
var isEvaluated = false; | |
return function () { | |
if (!(isEvaluated || ((isEvaluated = true), false))) | |
result = expressionAsFunction(); | |
return result; | |
}; | |
} | |
function force(promise) { | |
return promise(); | |
} | |
function cons(car, cdr) { | |
return [car, cdr]; | |
} | |
function next(n) { | |
return cons(n, delay(function () {return next(n + 1);})); | |
} | |
function head(stream) { | |
return stream[0]; | |
} | |
function tail(stream) { | |
return force(stream[1]); | |
} | |
var stream = next(0); | |
console.log(stream); | |
console.log(head(tail(tail(stream)))); //==> 2 |
How about if (!(isEvaluated || !(isEvaluated = true)))
rather than the , false
"hack".
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The local variable isEvaluated inside of delay wasn't changing state, and I wanted to fix that bug while not adding any extra lines of code.
At first I went with a solution where I initialized isEvaluated to 0, and then checked the truthiness of isEvaluated++. That solution yielded the desired functionality, but hypothetically was prone to a bug where isEvaluated could exceed the maximum value for an integer.
My new solution takes advantage of logical or and comma operators; thanks to short-circuiting, this solution should be fast as it will just return isEvaluated (when isEvaluated is true) without executing the logical or's right operand. The right operand assigns isEvaluated true, an expression which then evaluates to true - but thanks to the comma operator, the code "forcibly" returns false, which is the desired value; that is, the evaluated expression should differ in truthiness from all subsequent evaluations.