From ripley at stats.ox.ac.uk  Mon Sep 11 14:58:00 2006
From: ripley at stats.ox.ac.uk (Prof Brian Ripley)
Date: Mon, 11 Sep 2006 13:58:00 +0100 (BST)
Subject: [Rd] [R] function changes argument (PR#9216)
In-Reply-To: <x21wqieg3q.fsf@viggo.kubism.ku.dk>
References: <20060911113258.029B14C9CF@slim.kubism.ku.dk>
	<x21wqieg3q.fsf@viggo.kubism.ku.dk>
Message-ID: <Pine.LNX.4.64.0609111343460.974@gannet.stats.ox.ac.uk>

On Mon, 11 Sep 2006, Peter Dalgaard wrote:

> ripley at stats.ox.ac.uk writes:
> 
> > I can tell you where the problem is and a workaround:
> > 
> > f <- function(LL) for (ll in names(LL)) LL[[ll]]$txt<-"changed in f"
> > 
> > works.  The problem is that for() is directly exposing the elements of a 
> > list.
> > 
> > Of course, a more idiomatic construction would be
> > 
> > LL <- lapply(LL, function(x) x$txt <- "changed in f")
> > 
> > which also works.
> > 
> > The question is whether we do wish to change this to make the construction 
> > work as Andreas appears to intend.  The simplest solution is a 
> > precautionary duplicate in for(), which is potentially very expensive and 
> > almost always unneeded.
> > 
> > However, we already have
> > 
> > x <- 1:10
> > for(i in x) i <- pi
> > x
> > 
> > which does not change x, so I think the right solution is to make the list 
> > (LL here) read-only, which can be done cheaply.  That is also AFAICS what 
> > S does.
> 
> We could have a precautionary (virtual) assignment, effectively
> 
> for (`*tmp*` in L) { ll <- `*tmp*` ; .......}
> 
> I think this is what is supposed to happen in the R semantics, it also
> satisfies the convention that ll is defined at the end of the loop as
> the last value obtained. Assigning to the loop variable should not
> change the structure from which it comes, even if Andreas intended
> otherwise.
> 
> It's not the same as duplicating: it may change NAMED on the elements
> of L and cause extra duplication down the line, but not invariably so.
> 
> I suspect that the only reason it isn't what currently happens is
> that we have forgotten to diddle the NAMED flag in the implementation
> of for(), in the same way as is done for "<-".

Yes, on the list elements if the list is itself named, which I have 
already implemented. (I also added a shallow copy, which is needed if L is 
not to be read-only, but that seems not the closest analogy in 
retrospect.)

-- 
Brian D. Ripley,                  ripley at stats.ox.ac.uk
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272866 (PA)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595




[Rd] [R] function changes argument (PR#9216)
Prof Brian Ripley