Jonas Rauch
2012-Aug-22 07:56 UTC
[R] Class-attribute and method dispatch for the function-class
Hi everyone. I played with operator overloading for functions and came upon a few peculiarities. I basically wanted to do something like this:> Ops.function<-function(e1, e2) { > Op <- getMethod(.Generic) > if(missing(e2)) return(function(...) Op(e1(...)) ) > if(is.function(e2)) return(function(...) Op(e1(...),e2(...)) ) > function(...) Op(e1(...),e2) >}I expected to be able to do for example:> f <- function(x) cos(x^2 - 1) > g <- f^2 - fOf course g will not be very efficient, because it will call f twice for each evaluation. But the approach is very general and would often help to avoid anonymous functions. Now here is the problem: When I do the above, I get ?Error in f^2: non-numeric argument to binary operator? It appears that R does not do dispatch. I guess this is because f is not an object> is.object(f)[1] FALSE When I explicitly set the class of f to ?function? (i.e. the same as before) it seems like f becomes an object and everything works:> class(f)<-class(f) > g <- f^2 - f > gfunction(...) Op(e1(...),e2(...)) <environment: 0x026f29dc> Is there any way of getting dispatch to work without explicitly making functions an object? In addition I noticed some strange behavior with what I guess is the treatment of primitives. This might be a question better suited for r-devel, but since it ties in with the above I?ll still include it here: Starting with a function and a copy of it> u <- function(x) x+1 > v <- uwe have> is.object(u)[1] FALSE> is.object(v)[1] FALSE Now we explicitly set the class of u and it becomes an object, while the copy remains unchanged.> class(u)<-class(u) > is.object(u)[1] TRUE> is.object(v)[1] FALSE Now instead of u lets use a primitive function like sum and a copy mysum:> mysum <- sum > is.object(sum)[1] FALSE> is.object(mysum)[1] FALSE If we change the class of mysum, the original function sum becomes an object, too!> class(mysum)<-class(mysum) > is.object(mysum)[1] TRUE> is.object(sum)[1] TRUE Is this intended? Best regards, Jonas Rauch