Hi. I'm having difficulty following the advice given in help(Recall). Consider the two following toy functions: f1 <- function(n){ if(length(n)>1){return(sapply(n,f1))} matrix(n,n,n) } f2 <- function(n){ if(length(n)>1){return(sapply(n,Recall))} matrix(n,n,n) } f1() works as desired (that is, f(1:3), say, gives me a three element list whose i-th element is an i-by-i matrix whose elements are all i). But f2() doesn't. How do I modify either function to use Recall()? What exactly is Recall() calling here? -- Robin Hankin Uncertainty Analyst Southampton Oceanography Centre European Way, Southampton SO14 3ZH, UK tel 023-8059-7743
I doubt it's possible to use Recall inside a sapply like this. sapply (and lapply) make a copy of the function (FUN <- match.fun(FUN)) before passing it inside an internal function (rval <- .Internal(lapply(X, FUN)). So, while I'm not precisely sure how Recall is coded up, I bet that once it is copied inside of sapply (and lapply), it loses the context from which it was called. I can think of a couple ways around this. First, you could construct a for loop instead of a sapply and use Recall. Second, you could replace Recall by just asking R what the name of the calling function is and pass that in to sapply. Something like this should work: sapply(n, match.fun(sys.call()[[1]])) HTH, Robert -----Original Message----- From: Robin Hankin [mailto:r.hankin at soc.soton.ac.uk] Sent: Wednesday, March 30, 2005 3:28 AM To: R-help at stat.math.ethz.ch Subject: [R] Recall() and sapply() Hi. I'm having difficulty following the advice given in help(Recall). Consider the two following toy functions: f1 <- function(n){ if(length(n)>1){return(sapply(n,f1))} matrix(n,n,n) } f2 <- function(n){ if(length(n)>1){return(sapply(n,Recall))} matrix(n,n,n) } f1() works as desired (that is, f(1:3), say, gives me a three element list whose i-th element is an i-by-i matrix whose elements are all i). But f2() doesn't. How do I modify either function to use Recall()? What exactly is Recall() calling here? -- Robin Hankin Uncertainty Analyst Southampton Oceanography Centre European Way, Southampton SO14 3ZH, UK tel 023-8059-7743 ______________________________________________ R-help at stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
I believe that the function that Recall executes is the function in which Recall, itself, is evaluated -- not the function in which Recall appears. In normal cases these are the same but if you pass Recall to another function then they are not the same. Here Recall is being passed to sapply (which in turn is likely passing it to other functions). Because of lazy evaluation Recall does not get evaluated until it is found within sapply (or a function called by it or called by one called by it, etc.) and at that point its recalling the wrong function. AFAICS one cannot pass Recall to another function. You could rewrite the expression that uses sapply to use iteration instead or you could do it as shown below. In this example, the use of f2 within supply refers to the inner f2 which does not change even if the name of the outer f2 does. f2 <- function(n) { f2 <- function(n) if(length(n)>1) sapply(n,f2) else matrix(n,n,n) f2(n) } f3 <- f2 f2(1:3) f3(1:3) # gives same result On Wed, 30 Mar 2005 09:28:08 +0100, Robin Hankin <r.hankin at soc.soton.ac.uk> wrote:> Hi. > > I'm having difficulty following the advice given in help(Recall). > Consider the two > following toy functions: > > f1 <- function(n){ > if(length(n)>1){return(sapply(n,f1))} > matrix(n,n,n) > } > > f2 <- function(n){ > if(length(n)>1){return(sapply(n,Recall))} > matrix(n,n,n) > } > > f1() works as desired (that is, f(1:3), say, gives me a three element > list whose i-th element > is an i-by-i matrix whose elements are all i). > > But f2() doesn't. > > How do I modify either function to use Recall()? What exactly is > Recall() calling here? > > -- > Robin Hankin > Uncertainty Analyst > Southampton Oceanography Centre > European Way, Southampton SO14 3ZH, UK > tel 023-8059-7743 > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html >
On Wed, 30 Mar 2005, Robin Hankin wrote:> Hi. > > I'm having difficulty following the advice given in help(Recall). Consider > the two > following toy functions: > > > f1 <- function(n){ > if(length(n)>1){return(sapply(n,f1))} > matrix(n,n,n) > } > > f2 <- function(n){ > if(length(n)>1){return(sapply(n,Recall))} > matrix(n,n,n) > } > > > f1() works as desired (that is, f(1:3), say, gives me a three element list > whose i-th element > is an i-by-i matrix whose elements are all i). > > But f2() doesn't. > > How do I modify either function to use Recall()? What exactly is Recall() > calling here? >You can't use Recall here. I thought this was explicitly documented, but it turns out that it isn't, an omission I will fix. You don't need Recall, because R can easily have recursive functions without it (unlike S) - as you show in f1, the function can call itself - the problem with f1 is that it stops working if you change the name, but ?local shows how to get around this. This is probably the best way to implement recursion. - You can even implement Y, the "appplicative-order fixed point operator" to create anonymous recursive functions a la lambda calculus. -thomas