Created
February 25, 2012 02:21
-
-
Save adrusi/1905351 to your computer and use it in GitHub Desktop.
TCO in CoffeeScript
This file contains 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
tco = (fn) -> (args...) -> | |
if @recured? or @args? or @recur? | |
unless arguments.callee.noWarn | |
# here we are taking precautionary measures to make sure we don't | |
# accidentally overwrite some important properties in the context named | |
# "recured", "args" or "recur". The warnings can be disabled by setting | |
# the `noWarn` property of the function to true | |
throw new Error """ | |
calling a tail-recursive function in this context will overwrite the | |
properties "recured", "args" and "recur". | |
""" | |
@recured = false | |
@args = [] | |
@recur = (args...) => | |
@recured = true | |
@args = args | |
returnVal = fn.apply this, args | |
while true | |
if @recured | |
tempArgs = @args | |
@args = undefined | |
@recured = false | |
returnVal = fn.apply this, tempArgs | |
else | |
return returnVal | |
#============================================== | |
factorial = tco (n, acc = 1) -> | |
if n is 0 | |
acc | |
else | |
@recur n - 1, acc * n | |
console.log factorial 100000 | |
#============================================== | |
factorialWithCtx = tco (n, acc = 1) -> | |
if n is 0 | |
acc | |
else | |
@iterations++ | |
@recur n - 1, acc * n | |
counter = | |
iterations: 0 | |
console.log factorialWithCtx.call counter, 100000 | |
console.log counter.iterations |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment