[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Recursive anonymous functions?
- From: Gabor Grothendieck <ggrothendieck@...>
- Date: Fri, 23 Jul 2004 18:26:54 +0000 (UTC)
Gabor Grothendieck <ggrothendieck <at> myway.com> writes:
:
: Rici Lake <lua <at> ricilake.net> writes:
:
: :
: : On 22-Jul-04, at 9:31 PM, Gabor Grothendieck wrote:
: : >
: : > For example, we can invoke the anonymous factorial function
: : > evaluating it for the argument 3 like this:
: : >
: : > Recall = function(...)
: : > return debug.getinfo(2,"f").func(unpack(arg))
: : > end
: :
: : The use of the debug library is not advisable, unless you are actually
: : debugging. Furthermore, this will not work on the tail-recursive
: : implementation of factorial:
: :
: : print ((function(x, acc)
: : if x <= 1 then return acc
: : else return Recall(x - 1, x * acc)
: : end
: : end) (3, 1))
: :
: : stdin:1: attempt to call field `func' (a nil value)
:
: That's too bad; however, one can still do it in a consistent,
: but uglier, way for both examples by using
:
: debug.getinfo(1,"f").func
:
: inline like this:
:
: print ((function(x)
: if x == 0 then return 1
: else return x * debug.getinfo(1,"f").func(x - 1)
: end
: end) (3, 1))
:
: print ((function(x, acc)
: if x <= 1 then return acc
: else return debug.getinfo(1,"f").func(x - 1, x * acc)
: end
: end) (3, 1))
Here is a slight improvement. If one defines Recall to return the
function, itself, rather than the function evaluated, then Recall can
still be used in both the non-tail recursion and tail recursion cases
like this:
Recall = function() return debug.getinfo(2,"f").func end
print ((function(x) -- non-tail recursion example
if x == 0 then return 1
else return x * Recall()(x-1)
end
end) (3))
print((function(x, acc) -- tail recursion example
if x <= 1 then return acc
else
local Recall = Recall()
return Recall(x - 1, x * acc)
end
end)(3,1))
We could have made this entirely symmetric by writing the
non-tail recursion case using the local redefinition of
Recall, as well, like this:
print ((function(x) -- non-tail recursion version 2
if x == 0 then return 1
else
local Recall = Recall()
return x * Recall(x-1)
end
end) (3))