Hi, Can someone help me understand why substitute(function(a) a + 1, list(a=quote(foo))) gives function(a) foo + 1 and not function(foo) foo + 1 The man page leads me to believe this is related to lazy evaluation of function arguments, but I'm not getting the big picture. Thanks, + seth Using R 2.4 alpha svn r39255
Question about substitute() and function def
7 messages · Seth Falcon, Duncan Murdoch, Robert Gentleman +2 more
On 9/14/2006 3:01 PM, Seth Falcon wrote:
Hi, Can someone help me understand why substitute(function(a) a + 1, list(a=quote(foo))) gives function(a) foo + 1 and not function(foo) foo + 1 The man page leads me to believe this is related to lazy evaluation of function arguments, but I'm not getting the big picture.
I think it's the same reason that this happens: > substitute(c( a = 1, b = a), list(a = quote(foo))) c(a = 1, b = foo) The "a" in function(a) is the name of the arg, it's not the arg itself (which is missing). Now a harder question to answer is why this happens: > substitute(function(a=a) 1, list(a=quote(foo))) function(a = a) 1 I would have expected to get "function(a = foo) 1". Duncan Murdoch
Duncan Murdoch wrote:
On 9/14/2006 3:01 PM, Seth Falcon wrote:
Hi, Can someone help me understand why substitute(function(a) a + 1, list(a=quote(foo))) gives function(a) foo + 1 and not function(foo) foo + 1 The man page leads me to believe this is related to lazy evaluation of function arguments, but I'm not getting the big picture.
I think it's the same reason that this happens:
> substitute(c( a = 1, b = a), list(a = quote(foo)))
c(a = 1, b = foo) The "a" in function(a) is the name of the arg, it's not the arg itself
yes, but the logic seems to be broken. In Seth's case there seems to be no way to use substitute to globally change an argument and all instances throughout a function, which seems like a task that would be useful. even here, I would have expected all instances of a to change, not some
(which is missing). Now a harder question to answer is why this happens:
> substitute(function(a=a) 1, list(a=quote(foo)))
function(a = a) 1
a bug for sure
I would have expected to get "function(a = foo) 1". Duncan Murdoch
______________________________________________ R-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Robert Gentleman, PhD Program in Computational Biology Division of Public Health Sciences Fred Hutchinson Cancer Research Center 1100 Fairview Ave. N, M2-B876 PO Box 19024 Seattle, Washington 98109-1024 206-667-7700 rgentlem at fhcrc.org
On Thu, 14 Sep 2006, Duncan Murdoch wrote:
I think it's the same reason that this happens:
> substitute(c( a = 1, b = a), list(a = quote(foo)))
c(a = 1, b = foo) The "a" in function(a) is the name of the arg, it's not the arg itself (which is missing). Now a harder question to answer is why this happens:
> substitute(function(a=a) 1, list(a=quote(foo)))
function(a = a) 1 I would have expected to get "function(a = foo) 1".
In Splus you do get what you expected. > substitute(function(a=a) 1, list(a=quote(foo))) function(a = foo) 1 > substitute(function(a=func(100))func(a), list(func=quote(myFunction))) function(a = myFunction(100)) myFunction(a) R's substitute does not appear to go into the 'formals' of a function definition when looking for names to replace. ---------------------------------------------------------------------------- Bill Dunlap Insightful Corporation bill at insightful dot com 360-428-8146 "All statements in this message represent the opinions of the author and do not necessarily reflect Insightful Corporation policy or position."
On Thu, 14 Sep 2006, Robert Gentleman wrote:
> substitute(c( a = 1, b = a), list(a = quote(foo)))
c(a = 1, b = foo) The "a" in function(a) is the name of the arg, it's not the arg itself
yes, but the logic seems to be broken. In Seth's case there seems to be no way to use substitute to globally change an argument and all instances throughout a function, which seems like a task that would be useful. even here, I would have expected all instances of a to change, not some
In Splus, substitute changes all "name" objects with the values given by the names on the list given as its second argument. In Splus the argument name in the formals list is not of class "name" - it is of class "character". Hence it is not substituted. I agree it would be handy if it were substituted. In R I'm not sure what class/mode the argument name in the formals list has. The formals list is a "pairlist" and the argument names are th names of the pairlist. What internal class/mode do they have? However, substitute() in R does not appear to go into formal arguments of a function at all. ---------------------------------------------------------------------------- Bill Dunlap Insightful Corporation bill at insightful dot com 360-428-8146 "All statements in this message represent the opinions of the author and do not necessarily reflect Insightful Corporation policy or position."
On 9/14/2006 3:49 PM, Robert Gentleman wrote:
Duncan Murdoch wrote:
On 9/14/2006 3:01 PM, Seth Falcon wrote:
Hi, Can someone help me understand why substitute(function(a) a + 1, list(a=quote(foo))) gives function(a) foo + 1 and not function(foo) foo + 1 The man page leads me to believe this is related to lazy evaluation of function arguments, but I'm not getting the big picture.
I think it's the same reason that this happens:
> substitute(c( a = 1, b = a), list(a = quote(foo)))
c(a = 1, b = foo) The "a" in function(a) is the name of the arg, it's not the arg itself
yes, but the logic seems to be broken. In Seth's case there seems to be no way to use substitute to globally change an argument and all instances throughout a function, which seems like a task that would be useful.
I think variables and argument names are fundamentally different things, so I don't see this as very surprising. It should take two steps to make a change like that. Use substitute() to change the variables, put the result in f, change the names of the formals using names(formals(f)) <- "foo". I'm not sure if there's a simple way to change the first "a" in the expression c(a=1, b=a), but there are probably convoluted ways to do it.
even here, I would have expected all instances of a to change, not some
(which is missing). Now a harder question to answer is why this happens:
> substitute(function(a=a) 1, list(a=quote(foo)))
function(a = a) 1
a bug for sure
Yes. Duncan
Duncan Murdoch <murdoch at stats.uwo.ca> writes:
> substitute(function(a=a) 1, list(a=quote(foo)))
function(a = a) 1
a bug for sure
Yes.
Hmm... The issue is that the argument to `function` is a pairlist (not LANGSXP), and we don't recurse into those. Any R object can turn up as part of objects of mode "call" (by various methods, not least call() constructions), and I don't think we want to substitute into any recursive object. However, it's unlikely that pairlists would be used for anything other than function arguments, so I suppose we could change the behaviour (special-casing calls to `function` is an alternative). Luke? To wit:
mode(quote(function(x)1)[[1]])
[1] "name"
mode(quote(function(x)1)[[2]])
[1] "pairlist"
mode(quote(function(x)1)[[3]])
[1] "numeric"
O__ ---- Peter Dalgaard ?ster Farimagsgade 5, Entr.B c/ /'_ --- Dept. of Biostatistics PO Box 2099, 1014 Cph. K (*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918 ~~~~~~~~~~ - (p.dalgaard at biostat.ku.dk) FAX: (+45) 35327907