Skip to content

Question about substitute() and function def

7 messages · Seth Falcon, Duncan Murdoch, Robert Gentleman +2 more

#
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
#
On 9/14/2006 3:01 PM, Seth Falcon 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".

Duncan Murdoch
#
Duncan Murdoch wrote:
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
a bug for sure

  
    
#
On Thu, 14 Sep 2006, Duncan Murdoch wrote:

            
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:

            
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:
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.
Yes.

Duncan
#
Duncan Murdoch <murdoch at stats.uwo.ca> writes:
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:
[1] "name"
[1] "pairlist"
[1] "numeric"