Andrew Hoerner
2013-Dec-29 03:27 UTC
[R] What purpose is served by reflexive function assignments?
Let us suppose that we have a function foo(X) which is called inside another function, bar(). Suppose, moreover, that the name "X" has been assigned a value when foo is called: X <- 2 bar(X=X){ foo(X) } I have noticed that many functions contain arguments with defaults of the form X=X. Call this reflexive assignment of arguments. How is foo(X=X) different from foo(X)? Isn't the environment from which X is located the parent environment of foo() in either case? Or if it looks first in the environment inside of foo, will it not immediately pop up to the parent environment if it is not found in foo? Are reflexive assignments just to keep X from being positionally assigned accidentally, or are they doing something deeper? Moreover, this is the only place I have seen people consistently using an equals sign in place of the usual "<-", and I am confident that there is some subtle difference in how the two assignment operators work, perhaps beyond the ken of lesser mortals like myself, that explains why the "=" is preferred in this particular application. Actually, although I would like to hear the deep answer, which I am sure has something to do with scoping, as everything really confusing in R does, my real question is, is there some rule of thumb by which one could decide whether or not to do a reflexive assignment in a function definition and be right most of the time? Lately I have gotten several "Error: Promise is already under evaluation" messages, and my current rule of thumb for dealing with this is to add reflexive assignment to the variable if it is missing and take it out if it is present. This seems to work, but it makes me feel unintelligent. Is there a better rule? I would be most grateful for anyone who could shed light on the subject. Sincerely, andrewH -- J. Andrew Hoerner Director, Sustainable Economics Program Redefining Progress (510) 507-4820 [[alternative HTML version deleted]]
Ista Zahn
2013-Dec-29 05:35 UTC
[R] What purpose is served by reflexive function assignments?
On Sat, Dec 28, 2013 at 10:27 PM, Andrew Hoerner <ahoerner at rprogress.org> wrote:> Let us suppose that we have a function foo(X) which is called inside > another function, bar(). Suppose, moreover, that the name "X" has been > assigned a value when foo is called: > > X <- 2 > bar(X=X){ > foo(X) > } > > I have noticed that many functions contain arguments with defaults of the > form X=X.An example would be really helpful here. Call this reflexive assignment of arguments. Why call this anything special? All this does is set the default value of the X argument. I'm not sure what makes this "reflexive", or why it needs a special descriptive term. How is foo(X=X)> different from foo(X)? Isn't the environment from which X is located thefoo(X) is hardcoded, foo(X = X) just sets a default.> parent environment of foo() in either case? Or if it looks first in the > environment inside of foo, will it not immediately pop up to the parent > environment if it is not found in foo? Are reflexive assignments just to > keep X from being positionally assigned accidentally, or are they doing > something deeper? Moreover, this is the only place I have seen people > consistently using an equals sign in place of the usual "<-", and I am > confident that there is some subtle difference in how the two assignment > operators work, perhaps beyond the ken of lesser mortals like myself, that > explains why the "=" is preferred in this particular application.Again, some examples would really help here.> > Actually, although I would like to hear the deep answer, which I am sure > has something to do with scoping, as everything really confusing in R does, > my real question is, is there some rule of thumb by which one could decide > whether or not to do a reflexive assignment in a function definition and be > right most of the time?I'm still not even sure what reflexive assignment means. Can you clarify, preferably with some examples.> > Lately I have gotten several "Error: Promise is already under evaluation" > messages, and my current rule of thumb for dealing with this is to add > reflexive assignment to the variable if it is missing and take it out if it > is present. This seems to work, but it makes me feel unintelligent. Is > there a better rule? I would be most grateful for anyone who could shed > light on the subject.Perhaps someone can, but you will certainly make their job easier if you provide a concrete example that produces this error. Best, Ista> > Sincerely, andrewH > > -- > J. Andrew Hoerner > Director, Sustainable Economics Program > Redefining Progress > (510) 507-4820 > > [[alternative HTML version deleted]] > > ______________________________________________ > R-help at 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.
Peter Langfelder
2013-Dec-29 05:56 UTC
[R] What purpose is served by reflexive function assignments?
On Sat, Dec 28, 2013 at 7:27 PM, Andrew Hoerner <ahoerner at rprogress.org> wrote:> Let us suppose that we have a function foo(X) which is called inside > another function, bar(). Suppose, moreover, that the name "X" has been > assigned a value when foo is called: > > X <- 2 > bar(X=X){ > foo(X) > } > > I have noticed that many functions contain arguments with defaults of the > form X=X. Call this reflexive assignment of arguments.Your example code makes little sense, it throws an error even before reaching foo():> X <- 2 > bar(X=X){Error: unexpected '{' in "bar(X=X){"> foo(X)Error: could not find function "foo"> }Error: unexpected '}' in "}" What you may have in mind is something like bar = function(X) { foo(X) } X<-2 bar(X=X) Note that bar(X=4) is different from bar(X<-4), as seen here: # Define a trivial function> bar = function(X) {X+2} > > X = 0 > bar(X=2)[1] 4 # Here only the formal argument X of function bar was set to 2; the global variable X was left untouched:> X[1] 0 # This assigns the value 4 to the global variable X and uses that value as the value for the first formal argument of bar():> bar(X<-4)[1] 6 # Note that X changed in the global environment> X[1] 4 What you call "reflexive assignment" X=X is not really: the left hand side is the formal argument of bar(), the right hand side is the variable X in the calling environment of bar() (in this case global environment). Oh yes, and it has absolutely nothing to do with defaults. If you use my example above, the default for the argument X is 2, but doing X=0 bar(X=X) will call the function with argument X=0, not X=2. When there is only one argument, saying X=X does not make much sense, but when there are many arguments, say bar = function(X=0, Y=0, Z=0) and you only want to set the argument Z to a value you call Z in the calling function, saying bar(Z=Z) makes perfect sense and is very different from saying bar(Z) which would set the argument X to value Z, and leave argument Z at the default. Hope this helps. Peter
David Winsemius
2013-Dec-29 06:09 UTC
[R] What purpose is served by reflexive function assignments?
On Dec 28, 2013, at 7:27 PM, Andrew Hoerner wrote:> Let us suppose that we have a function foo(X) which is called inside > another function, bar(). Suppose, moreover, that the name "X" has been > assigned a value when foo is called: > > X <- 2 > bar(X=X){ > foo(X) > } > > I have noticed that many functions contain arguments with defaults of the > form X=X. Call this reflexive assignment of arguments. How is foo(X=X) > different from foo(X)?The LHS X becomes a name, the RHS X will be looked up in the calling environment and fails if no value is positionally matched and then no X is found (at the time of the function definition.> Isn't the environment from which X is located the > parent environment of foo() in either case?Not really. The X in foo(X) will be whatever value is given as the argument when foo is called and it will be assigned to X inside the function body.> Or if it looks first in the > environment inside of foo, will it not immediately pop up to the parent > environment if it is not found in foo?With foo(X=X) the interpreter will first determine if an argument was offered: rm(X) foo <- function(Z=X) print(Z^3) foo(5) # No error. #[1] 125> Are reflexive assignments just to > keep X from being positionally assigned accidentally, or are they doing > something deeper? Moreover, this is the only place I have seen people > consistently using an equals sign in place of the usual "<-", and I am > confident that there is some subtle difference in how the two assignment > operators work, perhaps beyond the ken of lesser mortals like myself, that > explains why the "=" is preferred in this particular application.If you use`X <- value` in the argument list, then what is returned is only the value and the name `X` may be lost. Or in the case of data.frame morphed inot a strange name: d <- data.frame(X <- letters[1:3]) d X....letters.1.3. 1 a 2 b 3 c Since it does a deparse(substitute(.)) on the nameless expressions in the argument list.> > Actually, although I would like to hear the deep answer, which I am sure > has something to do with scoping, as everything really confusing in R does, > my real question is, is there some rule of thumb by which one could decide > whether or not to do a reflexive assignment in a function definition and be > right most of the time? > > Lately I have gotten several "Error: Promise is already under evaluation" > messages, and my current rule of thumb for dealing with this is to add > reflexive assignment to the variable if it is missing and take it out if it > is present. This seems to work, but it makes me feel unintelligent. Is > there a better rule? I would be most grateful for anyone who could shed > light on the subject. > > Sincerely, andrewH > > -- > J. Andrew Hoerner > Director, Sustainable Economics Program > Redefining Progress > (510) 507-4820 > > [[alternative HTML version deleted]] > > ______________________________________________ > R-help at 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.David Winsemius Alameda, CA, USA
Duncan Murdoch
2013-Dec-29 12:18 UTC
[R] What purpose is served by reflexive function assignments?
You posted this same question two weeks ago, received a reasonable question in response, and ignored it. If you want help on the list please respond to questions. If the discussion goes offline, please post a summary when it is done. Duncan Murdoch On 13-12-28 10:27 PM, Andrew Hoerner wrote:> Let us suppose that we have a function foo(X) which is called inside > another function, bar(). Suppose, moreover, that the name "X" has been > assigned a value when foo is called: > > X <- 2 > bar(X=X){ > foo(X) > } > > I have noticed that many functions contain arguments with defaults of the > form X=X. Call this reflexive assignment of arguments. How is foo(X=X) > different from foo(X)? Isn't the environment from which X is located the > parent environment of foo() in either case? Or if it looks first in the > environment inside of foo, will it not immediately pop up to the parent > environment if it is not found in foo? Are reflexive assignments just to > keep X from being positionally assigned accidentally, or are they doing > something deeper? Moreover, this is the only place I have seen people > consistently using an equals sign in place of the usual "<-", and I am > confident that there is some subtle difference in how the two assignment > operators work, perhaps beyond the ken of lesser mortals like myself, that > explains why the "=" is preferred in this particular application. > > Actually, although I would like to hear the deep answer, which I am sure > has something to do with scoping, as everything really confusing in R does, > my real question is, is there some rule of thumb by which one could decide > whether or not to do a reflexive assignment in a function definition and be > right most of the time? > > Lately I have gotten several "Error: Promise is already under evaluation" > messages, and my current rule of thumb for dealing with this is to add > reflexive assignment to the variable if it is missing and take it out if it > is present. This seems to work, but it makes me feel unintelligent. Is > there a better rule? I would be most grateful for anyone who could shed > light on the subject. > > Sincerely, andrewH >