I'm not sure if this is a known peculiarity or a bug, but I stumbled across what I think is very odd behavior from delayedAssign. In the below example x switches values the first two times it is evaluated.> delayedAssign("x", {x <- 2; x+3}) > x==x[1] FALSE> delayedAssign("x", {x <- 2; x+3}) > x[1] 5> x[1] 2 The ?delayedAssign documentation says that "after [evaluation], the value is fixed and the expression will not be evaluated again." However, this appears not to be true. Is this a bug, or just a good way to write extremely obfuscated code? Robert McGehee, CFA Geode Capital Management, LLC One Post Office Square, 28th Floor | Boston, MA | 02109 Direct: (617)392-8396 This e-mail, and any attachments hereto, are intended fo...{{dropped:14}}
For the amusement of the listserver: Making use of the counter-intuitive assignment properties of delayedAssign, a co-worked challenged me to construct a delayedAssign of 'x' that causes 'x' to change its value _every_ time it is evaluated. The example below does this; each time 'x' is evaluated it is updated to be the next value in the Fibonnacci sequence. cmd <- parse(text "delayedAssign(\"x\", { x <- y[1]+y[2] y[1] <- y[2] y[2] <- x eval(cmd) y[1] })") y <- c(0,1) eval(cmd) for (i in 1:20) print(x) [1] 1 [1] 1 [1] 2 [1] 3 [1] 5 [1] 8 [1] 13 [1] 21 [1] 34 [1] 55 [1] 89 [1] 144 [1] 233 [1] 377 [1] 610 [1] 987 [1] 1597 [1] 2584 [1] 4181 [1] 6765 Cheers, Robert -----Original Message----- From: r-devel-bounces at r-project.org [mailto:r-devel-bounces at r-project.org] On Behalf Of McGehee, Robert Sent: Wednesday, April 25, 2012 5:19 PM To: r-devel at r-project.org Subject: [Rd] delayedAssign changing values I'm not sure if this is a known peculiarity or a bug, but I stumbled across what I think is very odd behavior from delayedAssign. In the below example x switches values the first two times it is evaluated.> delayedAssign("x", {x <- 2; x+3}) > x==x[1] FALSE> delayedAssign("x", {x <- 2; x+3}) > x[1] 5> x[1] 2 The ?delayedAssign documentation says that "after [evaluation], the value is fixed and the expression will not be evaluated again." However, this appears not to be true. Is this a bug, or just a good way to write extremely obfuscated code? Robert McGehee, CFA Geode Capital Management, LLC One Post Office Square, 28th Floor | Boston, MA | 02109 Direct: (617)392-8396 This e-mail, and any attachments hereto, are intended fo...{{dropped:14}} ______________________________________________ R-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
On Apr 25, 2012, at 5:18 PM, McGehee, Robert wrote:> I'm not sure if this is a known peculiarity or a bug, but I stumbled across what I think is very odd behavior from delayedAssign. In the below example x switches values the first two times it is evaluated. > >> delayedAssign("x", {x <- 2; x+3}) >> x==x > [1] FALSE > >> delayedAssign("x", {x <- 2; x+3}) >> x > [1] 5 >> x > [1] 2 > > The ?delayedAssign documentation says that "after [evaluation], the value is fixed and the expression will not be evaluated again." However, this appears not to be true.It is actually true, the value is not evaluated twice: your evaluation of "x" has modified the value of "x" (hence it is no longer a promise) so what you get in the next evaluation is the value that you have set as a side-effect of the promise evaluation. However, the forced value of the promise it still the value returned by the evaluated expression. YOu can see that it is the case by simply adding a function with side-effect (like cat) into your expression.> Is this a bug, or just a good way to write extremely obfuscated code? >That is a good question and I don't know the answer. The docs don't say which value will be fixed so it could be either way, but intuitively I would expect the promise evaluation to override side-effects. Cheers, Simon
It is really strange that the delayedAssign is evaluated in the environment it is called from, and thus can have side effects. so x=2 y=3 delayedAssign("x", {y <- 7; y+3}) gives> x[1] 10> y[1] 7 Both x and y changed. More intuitive would have been the behavior x=2 y=3 delayedAssign("x", local({y <- 7; y+3}) )> x[1] 10> y[1] 3 which only changes x. Or, at least that should be the default behavior.... Michael -- View this message in context: http://r.789695.n4.nabble.com/delayedAssign-changing-values-tp4588108p4590242.html Sent from the R devel mailing list archive at Nabble.com.
On Apr 26, 2012, at 11:59 AM, ghostwheel wrote:> It is really strange that the delayedAssign is evaluated in the environment it is called from,Not quite, it is evaluated in the environment you specify - and you have control over both environments ... see ?delayedAssign> and thus can have side effects. > so > x=2 > y=3 > delayedAssign("x", {y <- 7; y+3}) > > gives >> x > [1] 10 >> y > [1] 7 > > Both x and y changed. > More intuitive would have been the behavior > x=2 > y=3 > delayedAssign("x", local({y <- 7; y+3}) ) >> x > [1] 10 >> y > [1] 3 > which only changes x. > Or, at least that should be the default behavior.... >That is questionable - I think it is more logical for both environments to be the same as default. Just think if it -- the point here is to access lazy evaluation which is exactly what it does - lazy evaluation takes place in the original environment, not in another one. Cheers, Simon> Michael > > -- > View this message in context: http://r.789695.n4.nabble.com/delayedAssign-changing-values-tp4588108p4590242.html > Sent from the R devel mailing list archive at Nabble.com. > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > >