[Rd] foo2Args()

Duncan Murdoch murdoch at stats.uwo.ca
Fri Jun 30 22:43:18 CEST 2006


On 6/30/2006 4:19 PM, Paul Gilbert wrote:
> I was just considering trying to clean up the arguments to a function 
> that calls other functions,
> and was playin with a suggestion Achim made during a conversation at 
> useR.  The idea is, instead of using list(), use a small function to 
> construct and check arguments. My hope was to be able to do this without 
> making it globally visible:
> 
> foo <- function(x, args=foo2Args()) {
>   foo2Args <- function(a=1, b=2){list(a,b)}
>   # above would actual do more testing of args
>   #now I would call foo2 with args, but to test just
>   args
>   }
>  
> Now,
> 
>  > foo(1)   # should I be surprized that this works
> [[1]]
> [1] 1
> 
> [[2]]
> [1] 2

I don't think it really works, it's just a coincidence that the answer 
matches your expectations:

 > foo(3)
[[1]]
[1] 1

[[2]]
[1] 2

Or maybe I am completely misunderstanding your expectations...

> 
>  > foo(1, args=foo2Args(a=2, b=10)) # or that this does not
> Error in foo(1, args = foo2Args(a = 2, b = 10)) :
>     could not find function "foo2Args"

This is a somewhat subtle thing about the way args are evaluated.  What 
is done makes lots of sense once you understand it:

  - When you specify an argument in the call, the expression you give is 
evaluated in the current context.  In the context where you made this 
call, foo2Args is not defined, hence the error.

  - When you specify a default for an argument, it is evaluated in the 
local context of the function evaluation.  So as a default, foo2Args is 
recognized, because it's a local variable within foo.

You also need to remember "lazy evaluation":  neither of the above 
actually take place until args is used.

R is pretty flexible, so it's probably possible to do whatever you 
intended here; can you describe exactly what you want to happen?

Duncan Murdoch



More information about the R-devel mailing list