[Rd] (PR#7951) DispatchOrEval missing in do_isfinite and do_isinfinite

lars@predict.com lars at predict.com
Fri Jul 15 01:26:50 CEST 2005


Hi,

I ran into another internal function that is missing S4 dispatch. It is 
the binary operator ":". Looking at the code, I see that it is actually 
a common problem. Other candidates are operators like "~", "&&", "||" 
and functions like: "length<-", "row", "col", "unlist", "cbind", etc. It 
would for instance be nice to be able to write a matrix class that has 
the same operators and functions as the built-in class. In general, I 
think that all the operators and functions associates with built-in 
types like vectors, lists, matrices and data frames should have S4 dispatch.

Thanks,
Lars

lars wrote:

> Hi,
>
> OK, if you try to explicitly make them generic, you are told that they 
> are implicitly already generic:
>
> > setGeneric("is.finite", function(from, ...) 
> standardGeneric("is.finite"))
> Error in setGeneric("is.finite", function(from, ...) 
> standardGeneric("is.finite")) :
>    "is.finite" is a primitive function;  methods can be defined, but 
> the generic function is implicit, and can't be changed.
>
> If you query about its genericness before you define you own generic, 
> you get:
>
> > isGeneric("is.finite")
> [1] FALSE
>
> But after you define you own generic, you get:
>
> > setMethod("is.finite", signature(x="TS"),
> +           function(x) {
> +              Data(x) = callNextMethod()
> +              x
> +           })
> [1] "is.finite"
>
> > isGeneric("is.finite")
> [1] TRUE
>
> This all makes some sense, but I am not familiar enough with he 
> internals to explain exactly why it is done this way. I think you will 
> fine that 'is.nan' behave exactly the same way.
>
> Thanks,
> Lars
>
>
> Prof Brian Ripley wrote:
>
>> These functions are not generic according to the help page.
>> The same page says explicitly that is.nan is generic.
>>
>> Where did you get the (false) idea that they were generic?
>>
>> On Thu, 16 Jun 2005 lars at predict.com wrote:
>>
>>> Full_Name: Lars Hansen
>>> Version: 2.1.0
>>> OS: SunOS 5.8
>>> Submission from: (NULL) (207.66.36.189)
>>>
>>>
>>> Hi,
>>>
>>> S4 method displacth does not work for the two generic functions 
>>> 'is.finite' and 'is.infinite'. It turns out that the C functions 
>>> 'do_isfinite' and 'do_isinfinite' in src/main/coerce.c are missing a 
>>> call to 'DispatchOrEval' (see do_isnan). Added in the call fixed the 
>>> problem. My functions no look like this:
>>>
>>> Form coerce.c:
>>>
>>> SEXP do_isfinite(SEXP call, SEXP op, SEXP args, SEXP rho)
>>> {
>>>    SEXP ans, x, names, dims;
>>>    int i, n;
>>>
>>>    if (DispatchOrEval(call, op, "is.finite", args, rho, &ans, 1, 1))
>>>        return(ans);
>>>
>>>    checkArity(op, args);
>>>    ...
>>>
>>> SEXP do_isinfinite(SEXP call, SEXP op, SEXP args, SEXP rho)
>>> {
>>>    SEXP ans, x, names, dims;
>>>    double xr, xi;
>>>    int i, n;
>>>
>>>    if (DispatchOrEval(call, op, "is.infinite", args, rho, &ans, 1, 1))
>>>        return(ans);
>>>
>>>    checkArity(op, args);
>>>    ...
>>
>>
>>
>



More information about the R-devel mailing list