R-alpha: assignment scoping

Ross Ihaka (ihaka@stat.auckland.ac.nz)
Wed, 29 May 1996 14:52:50 +1200


Date: Wed, 29 May 1996 14:52:50 +1200
From: Ross Ihaka <ihaka@stat.auckland.ac.nz>
Message-Id: <199605290252.OAA29733@stat.auckland.ac.nz>
To: r-testers@stat.math.ethz.ch
Subject: R-alpha: assignment scoping
In-Reply-To: <9605281039.AA07296@nokomis.stat.umn.edu>

Luke Tierney writes:
 > Assignment to subscripts is interpreted a bit differently in R and
 > S. In S, it creates a new local variable if one does not exist; in R
 > it doesn't.

What we do with:

	f <- function() { x[1] <- 3 ; x }

at present is clearly wrong.  It is a product of us trying to appear
to be call-by-value while not being willing to pay the price (anything
being mutated must be duplicated first).

There are a number of possible solutions:

1) Adopt a copy-on-modify strategy.  The function "[<-" duplicates
   its argument.  We tried this in the past, but the cost is very
   high.  consider for example:

	x <- numeric(1000)
	for(i in 1:1000) x[i] <- i

   Each time through the loop the array must be copied.  This
   generates 1000 copies of a 1000 element array.

2) Recognize that x[1] <- 3 is a mutation of a local object.  If there
   is no "x" in the current evaluation frame, find an x from somewhere
   else and make a local copy of it.  Then continue with the mutation.
   This is in the spirit of what we do at present.  The check for a
   local "x" adds a small cost.  This will maintain compatibility with S.

3) Claim that x[1] <- 3 is an error in this context.  Attempting to
   mutate a local x when there is no local x seems like a rather
   odd thing to want to do.

4) Fix the whole scoping business (this is what compiler-jocks like
   Luke are really after :-).  I like this idea too.  Perhaps all
   that is required (Luke?) is a scoping declaration like

	f <- function() local x=x # local x getting its value from the global
		{ x[1] <- 3 ; x}

   Variables not declared local must be global.
   Of course this would break S compatibility in a major way.

For this particular bit of software one of 2) or 3) seems like
the right option, but I would like to pursue something like 4).

	Ross
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
r-testers mailing list -- To (un)subscribe, send
subscribe	or	unsubscribe
(in the "body", not the subject !)  To: r-testers-request@stat.math.ethz.ch
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-