Re: [Rd] generics for primitive functions

From: Parlamis Franklin <fparlamis_at_mac.com>
Date: Sat 23 Sep 2006 - 18:44:50 GMT

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@r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>>



R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel Received on Sun Sep 24 04:48:56 2006

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.1.8, at Sun 24 Sep 2006 - 23:30:09 GMT.

Mailing list information is available at https://stat.ethz.ch/mailman/listinfo/r-devel. Please read the posting guide before posting to the list.