Skip to content

Recall() and sapply()

3 messages · robin hankin, Gabor Grothendieck, Thomas Lumley

#
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 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:
#
On Wed, 30 Mar 2005, Robin Hankin wrote:

            
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