[R-sig-hpc] [R] recursion depth limitations

Simon Urbanek simon.urbanek at r-project.org
Fri Dec 14 13:46:51 CET 2012


On Dec 14, 2012, at 6:25 AM, Suzen, Mehmet wrote:

> On 14 December 2012 12:13, Suzen, Mehmet <suzen at acm.org> wrote:
>> On 13 December 2012 23:21, Rui Barradas <ruipbarradas at sapo.pt> wrote:
>>> But it does, each recursive call will load another copy of the function, and
>>> another copy of the variables used.
>>> In fact, the cost can become quite large since everything is loaded in
>>> memory again.
>>> 
>>> Hope this helps,
>>> 
>> 
>> Many thanks for the replies.
>> 
>> What about tail-recursion?  I have seen that there were discussions
>> about this:
>> 
>> https://stat.ethz.ch/pipermail/r-help/2006-April/102873.html
>> 
>> Since it was 6 years ago, maybe now things are little different.
> 
> 
> Isn't it logical to translate any recursive function to tail-recursive
> internally? While tail-recursive
> version returns a value but the operation is essentially the same. I don't know
> how difficult to do it generically but maybe there is an advantage of
> keeping recursion
> as it is. What would that advantage be?
> 
> For example, tail recursion would run but not the recursive version:
> 
>> options(expressions=500000)
>> f <- function(x) if(x >0) f(x-1);
>> system.time(f(10000000))
> Error: C stack usage is too close to the limit
> Error: C stack usage is too close to the limit
>> f1<-function(x) x-1
>> f <- function(x) f1(x);
>> system.time(f(10000000))
>   user  system elapsed
>      0       0       0
> 
> 

You may be a bit misinformed about with tail recursion means - it still needs to evaluate the function for each recursion step, the only difference is that in such special case there is no additional information that needs to be stored -- and you have also proven why it's not as simple as you think:

> f <- function(x) if(x >0) f(x-1)
> (f(100))
NULL

> f1<-function(x) x-1
> f <- function(x) f1(x);
> (f(100))
[1] 99

Your latter version doesn't actually do anything anywhere close to the recursion you defined. R doesn't have tail recursion elimination and as Thomas pointed out in the cited post it would break some existing things if it did (call frame introspection etc.). [Whether it would be ok to break it for the sake of optimization is another question]

Note that in all such cases you can easily write the problem in an iterative fashion (admittedly it is less elegant -- but if you are dealing with such deep structures chances are that you probably care about efficiency and to go native code anyway).

Cheers,
Simon



More information about the R-sig-hpc mailing list