Skip to content

detecting entry into a recursive function

6 messages · Benjamin Tyner, Bert Gunter, Duncan Murdoch +1 more

#
Given a function that calls itself, what's the best way to detect the 
entry point? The best I came up with is:

   IsEntryPoint <- function(){

     par <- sys.call(-1L)[[1]]
     grandpar <- sys.call(-2L)[[1]]

     !identical(par, grandpar)
   }

but this won't work for functions that don't directly call themselves; 
for example, in this one the paste gets inserted in the call stack, so i 
is always TRUE.

   f <- function(d){

     i <- IsEntryPoint()

     if(d > 1L) paste(d, f(d-1L))
   }

Any ideas?

Regards,
Ben
#
On 02/17/2013 12:55 PM, Benjamin Tyner wrote:
Hi Ben,
There are a number of ways to do this, from simply having a flag that 
has one value at the initial call to the function and another value when 
the function calls itself. for an example of this, see the code for the 
"sizetree" function in the plotrix package, in particular the 
"firstcall" argument.

Jim
#
Thanks Jim -- I had considered this approach; is there any way to "hide" 
such arguments from users?
Jim Lemon wrote:
#
Make the flag an attribute of the function? Unless the user looks at
the attributes, it will be "invisible."

(Not sure this does what you want, but maybe it's useful.)

-- Bert
On Sun, Feb 17, 2013 at 7:03 AM, Benjamin Tyner <btyner at gmail.com> wrote:

  
    
#
On 13-02-17 10:03 AM, Benjamin Tyner wrote:
Don't export the recursive function, just a non-recursive function that 
calls it.

Duncan Murdoch
#
On 02/18/2013 02:03 AM, Benjamin Tyner wrote:
Hi Ben,
I played around with your solution for a while and if the first argument 
to the function changes with each recursive call, you may be able to do 
it like this:

factorial<-function(x) {
  cat(x,"\n")
  if(as.character(x) == as.character(sys.call())[2])
   cat("I\'m the first!\n")
  if(x>1) x<-x*factorial(x-1)
  return(x)
}

factorial(3)
factorial(4)
...

Jim