[R] Class-attribute and method dispatch for the function-class

Jonas Rauch jonas.rauch at googlemail.com
Wed Aug 22 09:56:43 CEST 2012


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 - f

Of 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
> g
function(...) 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 <- u
we 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



More information about the R-help mailing list