Deepayan Sarkar
2006-Oct-09 20:13 UTC
[R] dispatch on functions (was: Re: ifelse(logical, function1, function2) does not work)
On 10/7/06, Gabor Grothendieck <ggrothendieck at gmail.com> wrote:> I have noticed that dispatch on functions seems not to work > in another case too. We define + on functions (I have ignored > the niceties of sorting out the environments as we don't really > need it for this example) but when we try to use it, it fails even > though in the second example if we run it explicitly it succeeds: > > > "+.function" <- function(x, y) function(z) x(z) + y(z) > > sin+cos > Error in sin + cos : non-numeric argument to binary operator > > "+.function"(sin, cos) > function(z) x(z) + y(z) > <environment: 0x01c4ae7c>I think that's because> oldClass(sin)NULL ?S3groupGeneric says: Note that a method will used for either one of these groups or one of its members _only_ if it corresponds to a '"class"' attribute, as the internal code dispatches on 'oldClass' and not on 'class'. This is for efficiency: having to dispatch on, say, 'Ops.integer' would be too slow. To generalise your example, Ops.function <- function (e1, e2 = NULL) { FUN <- get(.Generic, envir = parent.frame(), mode = "function") ans <- function(x) { if (is.null(e2)) "FUN"(e1(x)) else "FUN"(e1(x), if (is.function(e2)) e2(x) else e2) } oldClass(ans) <- "function" ans } gives me:> oldClass(sin) <- oldClass(cos) <- "function" > (sin^2 + cos^2)(runif(10, 0, 2 * pi))[1] 1 1 1 1 1 1 1 1 1 1 I had expected the issue of environments to be non-trivial, but things seem to magically [1] work out. Deepayan [1] http://www.quotationspage.com/quote/776.html