[Rd] Recursion error after upgrade to R_2.11.1 [Sec=Unclassified] [Sec=Unclassified]

Kasper Daniel Hansen kasperdanielhansen at gmail.com
Fri Oct 8 06:12:46 CEST 2010


Troy

For what it's worth, the ExpressionSet / eSet class in Biobase from
Bioconductor has for a long time implemented a pass-by-reference
system, using amongst other stuff locked environments to make sure
things are read only.  You might find this useful to look at.

In general it is hard to complement on your use case without knowing
the details.  I often find that careful programming and profiling can
make R code much faster than initially hypotised.  Having said that,
sometimes (esp. for very big, read-only  objects) environments make
sense.

Kasper

On Thu, Oct 7, 2010 at 6:52 PM, Troy Robertson
<Troy.Robertson at aad.gov.au> wrote:
>> -----Original Message-----
>> From: Martin Maechler [mailto:maechler at stat.math.ethz.ch]
>> Sent: Thursday, 7 October 2010 9:50 PM
>> To: Troy Robertson
>> Cc: 'Martin Morgan'; 'r-devel at R-project.org'; 'John Chambers'
>> Subject: Re: [Rd] Recursion error after upgrade to R_2.11.1
>> [Sec=Unclassified] [Sec=Unclassified]
>>
>>
>> >>>>> "TR" == Troy Robertson <Troy.Robertson at aad.gov.au>
>> >>>>>     on Thu, 7 Oct 2010 13:50:49 +1100 writes:
>>
>>     >>
>>     >> On 10/06/2010 06:12 PM, Troy Robertson wrote:
>>     >> > Hi all,
>>     >> >
>>     >> > After no replies to my previous message I thought I
>> might show some
>>     >> > code to demonstrate the change and again seek any
>>     >> explanation for the
>>     >> > error now thrown by my code after upgrading from
>> 2.10.1 to 2.11.1.
>>     >> >
>>     >> > Thanks
>>     >> > Troy
>>     >> > --------------------------------------------------------
>>     >> > setClass("PortableObject",
>>     >> >         representation(test1    = "character"),
>>     >> >
>>     >> >         prototype(      test1   = ""),
>>     >> >           contains = ".environment"
>>     >> > )
>>     >> >
>>     >> > setMethod("initialize", "PortableObject",
>>     >> >     function(.Object, ...,
>> .xData=new.env(parent=emptyenv())) {
>>     >> >                 .Object <- callNextMethod(.Object, ...,
>>     >> .xData=.xData)
>>     >> >
>>     >> >                 .Object at test1 <- "Foo"
>>     >> >                 # Following line works under 2.10.1
>> but now throws
>>     >> >                 # Error: evaluation nested too deeply:
>>     >> infinite recursion / options(expressions=)?
>>     >> >                 #####.Object[["test2"]] <- "Bar"
>>     >> >                 # The following does what I want though
>>     >> >                 .Object$test3 <- "Baa"
>>     >> >
>>     >> >                 return(.Object)
>>     >> >         }
>>     >> > )
>>     >> >
>>     >> > e <- new("PortableObject")
>>     >>
>>     >> The explicit example does help -- it's clear what bug you are
>>     >> encountering. Here's the code in R-2.10
>>     >>
>>     >> > selectMethod("[[<-", ".environment")
>>     >> Method Definition:
>>     >>
>>     >> function (x, i, j, ..., value)
>>     >> {
>>     >> call <- sys.call()
>>     >> call[[2]] <- x at .Data
>>     >> eval.parent(call)
>>     >> x
>>     >> }
>>     >>
>>     >>
>>     >> and 2.11.1
>>     >>
>>     >> > selectMethod("[[<-", ".environment")
>>     >> Method Definition:
>>     >>
>>     >> function (x, i, j, ..., value)
>>     >> {
>>     >> .local <- function (x, i, j, ..., exact = TRUE, value)
>>     >> {
>>     >> call <- sys.call()
>>     >> call[[2]] <- x at .Data
>>     >> eval.parent(call)
>>     >> x
>>     >> }
>>     >> .local(x, i, j, ..., value = value)
>>     >> }
>>     >>
>>     >> Apparently the 'exact' argument has been added, and because
>>     >> the method signature differs from the generic, a .local
>>     >> function is created. That 'sys.call()' originally returned
>>     >> the environment in which the generic was called, but now it
>>     >> returns the environment in which .local is defined. And so
>>     >> eval() keeps evaluating .local(). This I think is a bug.
>>
>>     TR> Yes, afer the email from William Dunlop, I found this
>> difference in the methods between 2.10.1 and 2.11.1
>>     TR> I had a play and by adding my own method to overload
>> "[[<-" for my PortableObject was able to reinstate the
>> original functionality without the recursive error.
>>
>>     TR> setMethod("[[<-", "PortableObject",
>>     TR> function (x, i, j, ..., value)
>>     TR> {
>>     TR> call <- sys.call()
>>     TR> call[[2]] <- x at .Data
>>     TR> eval.parent(call)
>>     TR> x
>>     TR> }
>>     TR> )
>>
>>     >>
>>     >> For what it's worth, if I were interested in minimizing
>>     >> copying I would set up initialize so that it ended with
>>     >> callNextMethod(<...>), on the hopes that the method
>>     >> eventually called would take care not to make too many copies
>>     >> on slot assignment.
>>     >>
>>     >> Martin
>>     >>
>>
>>     TR> Hmmm, not sure what you mean here?  My code passes
>> objects such as these as parameters to other S4 classes which
>> alter their data.  If the .xData slot is used then I have no
>> need to return the object.  No copy-on-change is performed
>> but data held by the PortableObject is modified.  This speeds
>> up my execution time by a LARGE amount.
>>
>>     TR> I could very well have things all arse-about, having
>> come from a Java OO background, but this is the only way I
>> have been able to create a pass-by-reference paradigm using
>> S4 classes.  Any suggestions for alternative solutions would
>> be greatfully received.
>>
>>     TR> Troy
>>
>> R 2.12.2 (currently beta) has in its NEWS :
>>
>>     o A facility for defining reference-based S4 classes (in the OOP
>>       style of Java, C++, etc.) has been added experimentally to
>>       package methods; see ?ReferenceClasses.
>>
>> ---> Please get R-2.12.2 beta and tell here about your
>> experiences. John Chambers (you have in CC) will be
>> particularly interested in your feedback.
>>
>> Martin Maechler, ETH Zurich
>>
>>
>
> Well...
>
> Just been having a read of the doco for the new reference classes.
> This opens up a whole new world in R doesn't it.  Very exciting.
> Except for the fact that it negates a lot of what I have been doing on top of S4 objects.  I will probably now be rewritting a lot of code.  Ouch!
>
> I'll start having a bit of a play and exploring this new way of doing things and let you know how I go.
> Will probably have questions along the way too.
>
> Thank you to everyone involved for their hard work.
>
> Troy
> ___________________________________________________________________________
>
>    Australian Antarctic Division - Commonwealth of Australia
> IMPORTANT: This transmission is intended for the addressee only. If you are not the
> intended recipient, you are notified that use or dissemination of this communication is
> strictly prohibited by Commonwealth law. If you have received this transmission in error,
> please notify the sender immediately by e-mail or by telephoning +61 3 6232 3209 and
> DELETE the message.
>        Visit our web site at http://www.antarctica.gov.au/
> ___________________________________________________________________________
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>



More information about the R-devel mailing list