[R] dispatch on functions (was: Re: ifelse(logical, function1, function2) does not work)
Deepayan Sarkar
deepayan.sarkar at gmail.com
Mon Oct 9 22:13:23 CEST 2006
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
More information about the R-help
mailing list