Hi. I'm pretty new to R, but I've been programming in other languages for some time. I have a couple of questions regarding programming with function objects. 1. Is there a way for a function to refer generically to all its actual arguments as a list? I'm thinking of something like the @_ array in Perl or the arguments variable in JavaScript. (By "actual" I mean the ones that were actually passed, as opposed to its formal arguments, as returned by formals()). 2. I have a package in which most of the functions have the form: the.function <- function(some, list, of, params) { return( some.other.function(the.list.of.params.to.this.function)); } Is there a way that I can use a loop to define all these functions? In general, I'm looking for all the information I can find on the subject of dynamic function definition (i.e. using code to automate the definition of functions at runtime). I'm most interested in introspection facilities and dynamic code generation. E.g. is it possible to write a module that "redefines itself" when sourced? Or can a function redefine itself when first run? Or how can a function find out about how it was called? FWIW, Some of the things I'd like to do are in the spirit of a decorator in Python, which is a function that take a function f an argument and return another function g that is somehow based on f. For example, this makes it very easy to write functions as wrappers to other simpler functions. TIA! KJ [[alternative HTML version deleted]]
On Tue, May 19, 2009 at 4:22 PM, Kynn Jones <kynnjo at gmail.com> wrote:> 2. I have a package in which most of the functions have the form: > > the.function <- function(some, list, of, params) { > ? ?return( some.other.function(the.list.of.params.to.this.function)); > } > > Is there a way that I can use a loop to define all these functions?How about something like this: funnames <- c('f1', 'f2', 'f3') funfactory <- function(n) { f <- function(...) NULL body(f) <- substitute(REPLACE(...), list(REPLACE=as.name(n))) f } funlist <- lapply(funnames, funfactory) "funlist" is a list of function objects that wrap calls to the named functions.> In general, I'm looking for all the information I can find on the subject of > dynamic function definition (i.e. using code to automate the definition of > functions at runtime). ?I'm most interested in introspection facilities and > dynamic code generation. ?E.g. is it possible to write a module that > "redefines itself" when sourced? ?Or can a function redefine itself when > first run? ?Or how can a function find out about how it was called?You should read chapter 6 of the "R Language Definition" manual, which is titled "Computing on the language". -- Steve Weston REvolution Computing One Century Tower | 265 Church Street, Suite 1006 New Haven, CT 06510 P: 203-777-7442 x266 | www.revolution-computing.com
hadley wickham
2009-May-19 21:38 UTC
[Rd] Qs: The list of arguments, wrapping functions...
> 1. Is there a way for a function to refer generically to all its actual > arguments as a list? ?I'm thinking of something like the @_ array in Perl or > the arguments variable in JavaScript. ?(By "actual" I mean the ones that > were actually passed, as opposed to its formal arguments, as returned by > formals()).match.call ? Hadley -- http://had.co.nz/
Wacek Kusnierczyk
2009-May-19 21:42 UTC
[Rd] Qs: The list of arguments, wrapping functions...
Kynn Jones wrote:> Hi. I'm pretty new to R, but I've been programming in other languages for > some time. I have a couple of questions regarding programming with function > objects. > 1. Is there a way for a function to refer generically to all its actual > arguments as a list? I'm thinking of something like the @_ array in Perl or > the arguments variable in JavaScript. (By "actual" I mean the ones that > were actually passed, as opposed to its formal arguments, as returned by > formals()). >a quick shot from a naive r user: f = function(a=1, b, ...) as.list(match.call()[-1]) f(2) f(b=2) f(1,2,3)> 2. I have a package in which most of the functions have the form: > > the.function <- function(some, list, of, params) { > return( some.other.function(the.list.of.params.to.this.function)); > } > > Is there a way that I can use a loop to define all these functions? >what do you mean, precisely?> In general, I'm looking for all the information I can find on the subject of > dynamic function definition (i.e. using code to automate the definition of > functions at runtime). I'm most interested in introspection facilities and > dynamic code generation. E.g. is it possible to write a module that > "redefines itself" when sourced? Or can a function redefine itself when > first run? Or how can a function find out about how it was called? >another quick shot from a naive r user: f = function() assign( as.character(match.call()[[1]]), function() evil(), envir=parent.frame()) f f() f you can then use stuff like formals, body, match.call, parent.frame, etc. to have your function reimplement itself based on how and where it is called.> FWIW, Some of the things I'd like to do are in the spirit of a decorator in > Python, which is a function that take a function f an argument and return > another function g that is somehow based on f. For example, this makes it > very easy to write functions as wrappers to other simpler functions. >recall that decorators, when applied using the @syntax, do not just return a new function, but rather redefine the one to which they are applied. so in r it would not be enough to write a function that takes a function and returns another one; it'd have to establish the input function's name and the environment it resides in, and then replace that entry in that environment with the new function. yet another quick shot from the same naive r user: # the decorator operator '%@%' = function(decorator, definition) { definition = substitute(definition) name = definition[[2]][[2]] definition = definition[[2]][[3]] assign( as.character(name), decorator(eval(definition, envir=parent.frame())), envir=parent.frame()) } # a decorator twice = function(f) function(...) do.call(f, as.list(f(...))) # a function inv = function(a, b) c(b, a) inv(1,2) # 2 1 twice(inv)(1,2) # 1 2 # a decorated function twice %@% { square = function(x) x^2 } square(2) # 16 # another decorator verbose = function(f) function(...) { cat('computing...\n') f(...) } # another decorated function verbose %@% { square = function(x) x^2 } square(2) # computing... # 4 there is certainly a lot of space for improvements, and there are possibly bugs in the code above, but i hope it helps a little. vQ
Gabor Grothendieck
2009-May-19 23:14 UTC
[Rd] Qs: The list of arguments, wrapping functions...
match.call() will return the call. merge.zoo in the zoo package uses it if you need an example. as.list(match.call()) will return a list. list(...) will return the ... arguments as a list. $.proto in the proto package allows one to write p$f where p is a proto object and f is a function and p$f is the function f(p, ...), i.e. it provides a currying operation. The Defaults package allows one to dynamically change the default arguments of functions. On Tue, May 19, 2009 at 4:22 PM, Kynn Jones <kynnjo at gmail.com> wrote:> Hi. ?I'm pretty new to R, but I've been programming in other languages for > some time. ?I have a couple of questions regarding programming with function > objects. > 1. Is there a way for a function to refer generically to all its actual > arguments as a list? ?I'm thinking of something like the @_ array in Perl or > the arguments variable in JavaScript. ?(By "actual" I mean the ones that > were actually passed, as opposed to its formal arguments, as returned by > formals()). > > 2. I have a package in which most of the functions have the form: > > the.function <- function(some, list, of, params) { > ? ?return( some.other.function(the.list.of.params.to.this.function)); > } > > Is there a way that I can use a loop to define all these functions? > > In general, I'm looking for all the information I can find on the subject of > dynamic function definition (i.e. using code to automate the definition of > functions at runtime). ?I'm most interested in introspection facilities and > dynamic code generation. ?E.g. is it possible to write a module that > "redefines itself" when sourced? ?Or can a function redefine itself when > first run? ?Or how can a function find out about how it was called? > > FWIW, Some of the things I'd like to do are in the spirit of a decorator in > Python, which is a function that take a function f an argument and return > another function g that is somehow based on f. ?For example, this makes it > very easy to write functions as wrappers to other simpler functions. > > TIA! > > KJ > > ? ? ? ?[[alternative HTML version deleted]] > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >