[R] What purpose is served by reflexive function assignments?

Peter Langfelder peter.langfelder at gmail.com
Sun Dec 29 06:56:36 CET 2013


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



More information about the R-help mailing list