Dear Jens and Wacek:

I appreciate your answers very much.

I came up an example based on your comments.
I feel the example helped me to understand...(I could be missing your points
though :( )
If so, please let me know.
Simon pointed out the following link:
http://www.stat.auckland.ac.nz/mail/archive/r-downunder/2008-October/000300.html
I am still trying to understand it...
My question is how my conclusion (see at the end of the example below) drawn
from "lexical scope" perspective is related to
an understanding from an "environment" perspective (if an understanding from
"environment" perspective validly exists).

Thank you all again very much!

-Sean Zhang

#My little example is listed below
f1<-function(a=1,b=2) {print(a); print(b); print(a-b) }
f1()  #get 3, makes sense
f1(2,) #get 0, makes sense
a <- 10
b <- 20
f1(a=a+1,b=a)
a  #get 10  a is not changed outside function scope
b  #get 20, b is not changed outside function scope
a <- 10
b <- 20
f1(a <- a+1, b <- a)
a   #a is now 11, a is changed outside function
b   #b is now 11  b is changed outside function
a <- 10
b <- 20
f1({a=a+1},{b = a})
a #a is changed into 11
b #b is changed into a(i.e., 11)

a <- 10
b <- 20
f1((a=a+1),(b = a))
a #a is changed into 11
b #b is changed into a(i.e., 11)
#my conclusion based on testing the example above is below
#say argument is a, when used inside paraenthesis of
whatever.fun<-function()
#a<-something, (a=something) , and {a<-something}
#are the same. They all change the values outside the function's scope.
#Typically, this breaks the desired lexical scope convention. so it is
dangerous.
#Correct me, if my understanding is off.
#Also, how to interprete the above test results from an "environment"
perspective? evnironment vs. scope?

#big thanks. -Sean




On Thu, Mar 12, 2009 at 11:29 AM, "Jens Oehlschlägel" <oehl_l...@gmx.de>wrote:

> Sean,
>
> > would like to receive expert opinion to avoid potential trouble
> [..]
> > i think the following is the most secure way if one really
> > really has to do assignment in a function call
> >    f({a=3})
> > and if one keeps this convention, <- can be dropped altogether.
>
> secure is relative, since due to R's lazy evaluation you never know whether
> a function's argument is being evalutated, look at:
>
> > f<- function(x)TRUE
> > x <- 1
> > f((x=2)) # obscured attempt to assign in a function call
> [1] TRUE
> > x
> [1] 1
>
> Thus there is dangerous advice in the referenced blog which reads:
> "
> f(x <- 3)
> which means "assign 3 to x, and call f with the first argument set to the
> value 3
> "
> This might be the case in C but not in R. Actually in R "f(x <- 3)" means:
> call f with a first unevaluated argument "x <- 3", and if and only if f
> decides to evaluate its first argument, then the assignment is done. To make
> this very clear:
>
> > f <- function(x)if(runif(1)>0.5) TRUE else x
> > x <- 1
> > print(f(x <- x + 1))
> [1] TRUE
> > print(f(x <- x + 1))
> [1] 2
> > print(f(x <- x + 1))
> [1] 3
> > print(f(x <- x + 1))
> [1] TRUE
> > print(f(x <- x + 1))
> [1] 4
> > print(f(x <- x + 1))
> [1] 5
> > print(f(x <- x + 1))
> [1] TRUE
> > print(f(x <- x + 1))
> [1] 6
> > print(f(x <- x + 1))
> [1] TRUE
>
> Here it is unpredictable whether your assignment takes place. Thus
> assigning like f({x=1}) or f((x=1))is the maximum dangerous thing to do:
> even if you have a code-reviewer and the guy is aware of the danger of
> f(x<-1) he will probably miss it because f((x=1)) does look too similar to a
> standard call f(x=1).
>
> According to help("<-"), R's assignment operator is rather "<-" than "=":
>
> "
> The operators <- and = assign into the environment in which they are
> evaluated. The operator <- can be used anywhere, whereas the operator = is
> only allowed at the top level (e.g., in the complete expression typed at the
> command prompt) or as one of the subexpressions in a braced list of
> expressions.
> "
>
> So my recommendation is
> 1) use R's assignment operator with two spaces around (or assign()) and
> don't obscure assignments by using C's assignment operator (or other
> languages equality operator)
> 2) do not assign in function arguments unless you have good reasons like in
> system.time(x <- something)
>
> HTH
>
>
> Jens Oehlschlägel
>
> P.S. Disclaimer: you can consider me biased towards "<-", never trust
> experts, whether experienced or not.
>
> P.P.S. a puzzle, following an old tradition:
>
> What is going on here? (and what would you need to do to prove it?)
>
> > search()
> [1] ".GlobalEnv"        "package:stats"     "package:graphics"
>  "package:grDevices" "package:utils"     "package:datasets"
>  "package:methods"
> [8] "Autoloads"         "package:base"
> > ls(all.names = TRUE)
> [1] "y"
> > y
> [1] 1 2 3
> > identical(y, 1:3)
> [1] TRUE
> > y[] <- 1  # assigning 1 fails
> > y
> [1] 1 2 3
> > y[] <- 2  # assigning 2 works
> > y
> [1] 2 2 2
> >
> > # Tip: no standard packages modified, no extra packages loaded, neither
> classes nor methods defined, no print methods hiding anything, if you would
> investigate my R you would not find any false bottom anymore
> >
> > version
>               _
> platform       i386-pc-mingw32
> arch           i386
> os             mingw32
> system         i386, mingw32
> status
> major          2
> minor          8.1
> year           2008
> month          12
> day            22
> svn rev        47281
> language       R
> version.string R version 2.8.1 (2008-12-22)
>
> --
> Psssst! Schon vom neuen GMX MultiMessenger gehört? Der kann`s mit allen:
> http://www.gmx.net/de/go/multimessenger01
>

        [[alternative HTML version deleted]]

______________________________________________
R-help@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.

Reply via email to