lua-users home
lua-l archive

Re: Recursive anonymous functions?

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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))

AltStyle によって変換されたページ (->オリジナル) /