ESS assigns .Last.value to the wrong place in R

Kurt Hornik Kurt.Hornik@wu-wien.ac.at
Thu, 8 Aug 2002 22:33:50 +0200


>>>>> David Brahm writes:

> I repeat my emails of 11/15/01 and 2/26/02, since it looks like this ESS bug is
> still not fixed in ESS 5.1.23, and I think some resolution is needed.

> When help() is invoked, ESS makes a copy of .Last.value in the .GlobalEnv,
> which is *not* where R normally stores it (R stores it in package:base).
> When this copy becomes stale it leads to wrong answers.  The bug is in
> essd-r.el, lines 63-64:

>     (ess-retr-lastvalue-command
>      . ".Last.value <- get(\".ess.lvsave\",inherits=TRUE)\n") ; envir=1

> which should be changed (as I have done on my machine) to:

>     (ess-retr-lastvalue-command
>      . "assign(\".Last.value\", .ess.lvsave, envir=NULL)\n") ; package:base

> Here's an example of how things can go wrong:
R> find(".Last.value")
>    [1] "package:base"
R> 0+1
>    [1] 1
R> .Last.value
>    [1] 1
R> ?seq       # At this point a stale copy of .Last.value is written to pos=1
R> 0+2
>    [1] 2
R> .Last.value                                        # WHOOPS!  WRONG VALUE!
>    [1] 1
R> find(".Last.value")          # The right value is masked by the stale copy
>    [1] ".GlobalEnv"   "package:base"


> Whenever I bring this up, a debate begins over who should change (ESS
> or R).  In particular, my solution will not work if package:base is
> "sealed".  Here's the tail end of our last discussion:

> Rich Heiberger <rmh@surfer.sbm.temple.edu> wrote:
>> ... The effect of sealing package:base from the user means that R will have
>> to store .Last.value in .GlobalEnv, which is the place ESS is using.  This
>> in effect is your solution 2) Change R to store .Last.value in .GlobalEnv
>> 
>> Net result, ESS does not change behavior, R has already promised to
>> change behavior.

> and Kurt Hornik <hornik@mithrandir.hornik.net> replied:
>> Not at all.  Sealing base does not mean that .Last.value needs to be
>> stored in the user's workspace.  The standard approach would be to use
>> dynamic variables which are in fact functions with internal state
>> (typically maintained in their environments).  E.g., .libPaths() in R
>> 1.4 or better illustrates the idea.  There might be a .Last.value()
>> along these lines.  The most prominent example is options() which is
>> used for manipulating .Options (see also the R FAQ): this is currently
>> visible to the user but it really should not.
>> 
>> Let me discuss our strategy re .Last.value with some r-core members.

> Also, Rodney Sparapani <rsparapa@post.its.mcw.edu> suggested:
>> I may be in way over my head here.  But, I think there is a 4th solution.
>> Have ESS save .Last.value as some other variable in .GlobalEnv like
>> .Last.value.saved.  That way .Last.value would not be hidden, and it could
>> still be retreived if someone had done a help() or whatever.

> Any more thoughts?

I had raised this issue with a couple of r-core people, but without
coming to a final conclusion.  I think the underlying issue is rather
subtle: what is attempted by playing with .Last.value is somehow to
restore the 'state' of the system before ESS started 'invisibly'
interacting with it.  I have no idea if this makes sense conceptually in
a multithreaded setting.  (And the same applies to .Last.value, up to
some extent.)

I would actually prefer that we stop playing with .Last.value, and
document this.  If not, David's suggestion about assigning in envir =
NULL (i.e., the base package) is certainly preferable to what ESS
currently has, but will need to reviewed once name spaces are fully in
place.

-k
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-devel-request@stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._