[Rd] generics for primitive functions

Pr. Jean-Michel Collard jmc at math.ethz.ch
Mon Sep 25 00:57:42 CEST 2006


Short reply -- I'm away from regular web access for 2 days.

The exception would break a simple test (is.object() essentially) and
likely have serious efficiency problems.  You'd need a better argument, I
suspect.

> Yes, I figured I might have entered the forbidden zone (one hint was
> that I had to set the group method to achieve my goal -- an attempt
> to directly set a method for the 'sqrt' function was frustrated in
> the manner you suggest).  I have two followup questions and a request:
>
> (i) Should I expect that the fix will be to seal group methods for
> groups that contain primitive functions and signatures comprising
> only basic data types, or that group methods will remain unsealed
> (and thus still work as desired for non-primitive underliers) and
> some other block applied?
>
> (ii) In "How Methods Work" (pg. 8), you write: "So long as
> computations access the generic function through getGeneric(), most
> computations should be unaffected."  I took this as a suggestion that
> calls like getGeneric("sqrt")(4) were the suggested way to operate
> with primitives under S4.  What does it really mean?
>
> Now the request (with some explanation).  I am not really interested
> in redefining primitives for class 'numeric.'  What I really want to
> do is define working non-primitive variants of primitives for class
> 'expression'.  I have already done this for a class 'Expression'
> which contains 'expression' as you suggest, but I have been somewhat
> frustrated to go through the formality of dealing with a "custom"
> class for this purpose (as it adds unnecessary bulk and coercion to
> my code).  Since AFAIK none of the primitives in the 'Ops' or 'Math'
> groups work for objects of class 'expression' anyway, I don't see
> what purity we are retaining by sealing the methods on these
> functions for signatures comprising only objects of class 'expression'.
>
> I'd like to request (as a feature change) that these methods be
> unsealed for signatures comprising only objects of class
> 'expression'.  More broadly, I think it would be nice to unseal
> methods for primitive functions on all signatures for which the
> primitive would produce an error.  Sealing things that don't work is
> slightly cruel.  Perhaps a 'sealedPrimitives' option that the
> efficiency guys could check and freaks like me (who want to make 2+2
> = 3) could uncheck would be the simplest solution.  Of course I make
> this request humbly -- I have no idea what might be the cost in code
> of the discrimination I am requesting.
>
> Franklin
>
> On Sep 23, 2006, at 3:35 AM, John Chambers wrote:
>
>> Probably a bug, but not at all the one you imply.  You have found a
>> way to subvert a guarantee in R that methods for primitives can
>> never be redefined for basic data types.
>>
>> As you no doubt found, but didn't show us, so long as you say sqrt
>> (4) the result is correct.  (Your "Works" should really read
>> "Gotcha!").
>>
>> Since a large amount of effort and not a little programming pain
>> has been spent retaining the purity of primitive calls to satisfy
>> the efficiency lobby, it's not clear what should happen when one
>> insists on calling the generic function directly.  Either an error
>> or just a call to the primitive would be the two likely
>> candidates.  Not what happens in your first example though.
>>
>> If you really want a "numeric" class that does something different
>> for sqrt(), define an S4 class that contains "numeric"
>> > setClass("WeirdNumber", contains="numeric")
>> [1] "WeirdNumber"
>> > setMethod("Math", "WeirdNumber", function(x) "Weird")
>> [1] "Math"
>> > xx = new("WeirdNumber", 1:10)
>> > sqrt(xx)
>> [1] "Weird"
>>
>>
>> Parlamis Franklin wrote:
>>> i think these two code snippets exhibit a bug.  they are
>>> identical  but for the inclusion of an initial line in snippet [2]
>>>
>>> [1]
>>> setMethod("Math", signature(x = "numeric"), function(x) "Works")
>>> getGeneric("sqrt")(4)
>>>
>>> [2]
>>> getGeneric("sqrt")(4)
>>> setMethod("Math", signature(x = "numeric"), function(x) "Works")
>>> getGeneric("sqrt")(4)
>>>
>>> these are my results, when each is run from a fresh R session
>>>
>>> [1]
>>>  > setMethod("Math", signature(x = "numeric"), function(x) "Works")
>>> [1] "Math"
>>>  > getGeneric("sqrt")(4)
>>> [1] "Works"
>>>
>>> [2]
>>>  > getGeneric("sqrt")(4)
>>> `__Deferred_Default_Marker__`
>>>  > setMethod("Math", signature(x = "numeric"), function(x) "Works")
>>> [1] "Math"
>>>  > getGeneric("sqrt")(4)
>>> `__Deferred_Default_Marker__`
>>>
>>> the section in "How Methods Work" that deals with this is
>>> unfinished,  but i think it suggests that getGeneric("sqrt")(4)
>>> should work out of  the box.
>>>
>>> franklin parlamis
>>>
>>>  > version
>>>                 _
>>> platform       powerpc-apple-darwin8.7.0
>>> arch           powerpc
>>> os             darwin8.7.0
>>> system         powerpc, darwin8.7.0
>>> status         beta
>>> major          2
>>> minor          4.0
>>> year           2006
>>> month          09
>>> day            22
>>> svn rev        39471
>>> language       R
>>> version.string R version 2.4.0 beta (2006-09-22 r39471)
>>>
>>> ______________________________________________
>>> R-devel at r-project.org mailing list
>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>>
>>>
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>


-- 
Fluctut nec mergitur




More information about the R-devel mailing list