views:

75

answers:

2

Is there any way, given a function passed as a parameter, to alter its input parameter string before evaluating it?

Here's pseudo-code for what I'm hoping to achieve:

test.func <- function(a, b) {
    # here I want to alter the b expression before evaluating it:
    b(..., val1=a)
}

Given the function call passed to b, I want to add in a as another parameter without needing to always specify ... in the b call. So the output from this test.func call should be:

test.func(a="a", b=paste(1, 2))
"1"  "2"  "a"

Edit:

Another way I could see doing something like this would be if I could assign the additional parameter within the scope of the parent function (again, as pseudo-code); in this case a would be within the scope of t1 and hence t2, but not globally assigned:

t2 <- function(...) {
  paste(a=a, ...)
}

t1 <- function(a, b) {
  local( { a <<- a; b } )
}

t1(a="a", b=t2(1, 2))

This is somewhat akin to currying in that I'm nesting the parameter within the function itself.

Edit 2:

Just to add one more comment to this: I realize that one related approach could be to use "prototype-based programming" such that things would be inherited (which could be achieved with the proto package). But I was hoping for a easier way to simply alter the input parameters before evaluating in R.

A: 

What do you want to do to the B expression? Do you want to dynamically add behavior? Then there is a decorator pattern in your problem. Want to optionally add behavior? Proxy. Need to swap out one behavior for another under certain circumstances? Strategy.

You are far better off relying on design patterns - which work and make you more effective regardless of the language you use - than you are trying to use some language-specific feature that let's you mutate the behavior of a strategy.

+2  A: 

Have you check substitute? I don't know it satisfies you needs but you could use fact that it returns hidden list structure which you can modify as below

test.func <- function(a, b) {
    f <- substitute(b)
    f[["val1"]] <- a
    eval(f)
}

test.func(a="a", b=paste(1, 2))
# "1 2 a"
Marek
That's exactly what I was looking for. Thanks!
Shane