[Rd] S4 generics "missing"
Martin Maechler
maechler at stat.math.ethz.ch
Fri Jul 15 19:19:43 CEST 2005
Thank you, Lars, for persisting on this topic of
missing S4 generics!
[I'm diverting this away from the original bug report;
since this is really about future features rather than R bugs.]
Unfortunately it's not as easy as you might think.
o One reason is the fact that currently it is still necessary
for bootstrapping reasons that R "can run" with only the 'base'
package loaded, i.e. "methods" not available. This makes
it sometimes hard to S4-ize base functions.
o Then there have been performance issues hindering the
S4-ification of ``everything''.
Note that e.g. S4 classes , functions methods, etc are not really
proper C-level SEXPs which would speed up (and lead to clean
up) of the "methods" code base.
o One other problem is with function like cbind() which have
a signature starting with '...' : The need to be changed
before you can define methods for them.
We've recently started to discuss this issue within R core,
with constructive proposals by John Chambers, and I have been
strongly considering indeed to try the case of
cbind() and rbind() in particular.
I also hope that some of these issues will be addressed during
this summer and will eventually lead to much improved S4
facilities in R.
Martin Maechler, ETH Zurich
>>>>> "lars" == lars <lars at predict.com>
>>>>> on Fri, 15 Jul 2005 01:26:50 +0200 (CEST) writes:
lars> Hi,
lars> I ran into another internal function that is missing S4 dispatch. It is
lars> the binary operator ":". Looking at the code, I see that it is actually
lars> a common problem. Other candidates are operators like "~", "&&", "||"
lars> and functions like: "length<-", "row", "col", "unlist", "cbind", etc. It
lars> would for instance be nice to be able to write a matrix class that has
lars> the same operators and functions as the built-in class. In general, I
lars> think that all the operators and functions associates with built-in
lars> types like vectors, lists, matrices and data frames should have S4 dispatch.
lars> Thanks,
lars> Lars
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