Re: [Rd] Curry: proposed new functional programming, er, function.
> I've been playing around with this for a while. One flaw I found - it > doesn't handle nested Curries very well (the naive implementation in > roxygen/functional does). That's easily fixed: Curry <- function(FUN, ...) { args <- match.call(expand.dots = FALSE)$... args$... <- as.name("...") env <- parent.frame() if (is.name(FUN)) { fname <- FUN } else if (is.character(FUN)) { fname <- as.name(FUN) } else if (is.function(FUN)){ fname <- FUN # env$FUN <- FUN } else { stop("FUN not function or name of function") } curry_call <- as.call(c(list(fname), args)) f <- eval(call("function", as.pairlist(alist(... = )), curry_call)) environment(f) <- env f } Curry(Curry(foo,3),4) > e.g.: > > foo=function(x,y,z) x+y+z > Curry(Curry("foo",3),4)(3) > # 10 > > Curry(Curry(foo,3),4)(3) > # hangs > > foo4=function(a,b,c,d) > Curry(Curry(Curry("foo4",3),4),1)(3) > # hangs > > I was also curious if there was some trick to force a function eval when the > list of arguments got exhausted (for example, a triple Curry on foo above > would leave no arguments so would trigger eval into 10). I don't think that would be a good idea - there's a big difference between a function with no arguments and the result of calling that function. Hadley -- Assistant Professor / Dobelman Family Junior Chair Department of Statistics / Rice University http://had.co.nz/ __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
[Rd] equivalent to source() inside a package
Hi all: I'm working on a project that I have packaged for ease of distribution. The different simulations in the package share code, so obviously I have those parts organized as functions. Now, I want to show people my code, but the structure with the internal functions might be a little confusing to follow. One thing I tried was to have the code of the functions as their own R files in the R/ folder, and then using source() instead of calling the functions (with consistent variable names and such) but this didn't work. The goal is for the user to be able to see the entirety of the code in the interactive R session, i.e. with a standard package implementation: > library(wei.simulations) > sim1 function (seed=) { [stuff] a = internal_function1(data) [stuff] } I would like the user to see: > sim1 function (seed=) { [stuff] tmp = apply(data,1,mean) a = sum(tmp) #or whatever, this is just an example [stuff] } where I can change those two lines in their own file, and have the changes apply for all the simulation functions. I know this seems like a weird question to ask, but it would be useful for me to make it as foolproof as possible for the user to see all the simulation code (I'm presuming the user is a casual R user and not familiar with looking through package sources). Thanks Wei __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Curry: proposed new functional programming, er, function.
So here's the way I'm reading this: Original: curry_call is the function body you're constructing, which is itself just a one liner which calls the symbol FUN with the appropriate substitutions. call("function", [...]) calls the "function" function, which itself takes 2 arguments: the list of formal args and the function body. eval of this call returns the newly constructed function, which you assign to f. Then you assign the parent.frame() as the environment of f, except with the symbol FUN assigned as the original argument FUN. However, upon looking at the debugger, I find that env$FUN<-FUN assigns FUN in Global Scope if Curry is called from the top level. A nested Curry call then creates FUN=function(...) FUN([...]), a recursive infinite loop. New: The recursion is obviously removed now, but what's the new version do? As far as I can tell, it returns a structure like... function(...){function(...) {original_function_body(curried_arg, ...=...)}} Comparing and contrasting to the version in "functional" package: 1) quotes work (can do Curry(quote(foo), 2) where the "functional" version can't) 2) environment capture works in both constructions 3) Your new version is exceptionally transparent, as the function body gets stored so that when you print the body later, you can see the original As far as 0 argument functions, I understand the difference, that idea came from a programming language (q/kdb+) I know that supports a neat compact syntax for this: Suppose in R the function was f(x,y,z) x + y + z In q, one could do: f[1;2] // returns the curried form f[1;2] each (1 2 3 4 5) // equivalent to Map(function(z) f(1,2,z), 1:5) or Map(Curry(f, 1, 2), 1:5) f[1;2;3] // returns 6 f[1;2][3] // returns 6 Probably a slightly different but related concept - elided arguments, just a curry with automatic eval when all argument slots are filled. Thanks, this has been very enlightening. Yike On 5/25/2012 9:49 AM, Hadley Wickham wrote: That's easily fixed: Curry<- function(FUN, ...) { args<- match.call(expand.dots = FALSE)$... args$...<- as.name("...") env<- parent.frame() if (is.name(FUN)) { fname<- FUN } else if (is.character(FUN)) { fname<- as.name(FUN) } else if (is.function(FUN)){ fname<- FUN # env$FUN<- FUN } else { stop("FUN not function or name of function") } curry_call<- as.call(c(list(fname), args)) f<- eval(call("function", as.pairlist(alist(... = )), curry_call)) environment(f)<- env f } Curry(Curry(foo,3),4) e.g.: foo=function(x,y,z) x+y+z Curry(Curry("foo",3),4)(3) # 10 Curry(Curry(foo,3),4)(3) # hangs foo4=function(a,b,c,d) Curry(Curry(Curry("foo4",3),4),1)(3) # hangs I was also curious if there was some trick to force a function eval when the list of arguments got exhausted (for example, a triple Curry on foo above would leave no arguments so would trigger eval into 10). I don't think that would be a good idea - there's a big difference between a function with no arguments and the result of calling that function. Hadley __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] equivalent to source() inside a package
Is there a reason for not using a vignette or putting a file in the demo/ directory? This seems like the sort of thing for which they are intended. Paul On 12-05-25 03:33 PM, Wei Hao wrote: Hi all: I'm working on a project that I have packaged for ease of distribution. The different simulations in the package share code, so obviously I have those parts organized as functions. Now, I want to show people my code, but the structure with the internal functions might be a little confusing to follow. One thing I tried was to have the code of the functions as their own R files in the R/ folder, and then using source() instead of calling the functions (with consistent variable names and such) but this didn't work. The goal is for the user to be able to see the entirety of the code in the interactive R session, i.e. with a standard package implementation: library(wei.simulations) sim1 function (seed=) { [stuff] a = internal_function1(data) [stuff] } I would like the user to see: sim1 function (seed=) { [stuff] tmp = apply(data,1,mean) a = sum(tmp) #or whatever, this is just an example [stuff] } where I can change those two lines in their own file, and have the changes apply for all the simulation functions. I know this seems like a weird question to ask, but it would be useful for me to make it as foolproof as possible for the user to see all the simulation code (I'm presuming the user is a casual R user and not familiar with looking through package sources). Thanks Wei __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Curry: proposed new functional programming, er, function.
On Fri, May 25, 2012 at 3:14 PM, Yike Lu wrote: > So here's the way I'm reading this: > > Original: > curry_call is the function body you're constructing, which is itself just a > one liner which calls the symbol FUN with the appropriate substitutions. Yup. With a bit more infrastructure you could probably modify it so that multiple curries collapsed into the equivalent single curry. > call("function", [...]) calls the "function" function, which itself takes 2 > arguments: the list of formal args and the function body. > eval of this call returns the newly constructed function, which you assign > to f. Then you assign the parent.frame() as the environment of f, except > with the symbol FUN assigned as the original argument FUN. > > However, upon looking at the debugger, I find that env$FUN<-FUN assigns FUN > in Global Scope if Curry is called from the top level. > A nested Curry call then creates FUN=function(...) FUN([...]), a recursive > infinite loop. Yes, that was a really bad idea - not sure why I didn't see the problems when I first wrote it. > New: > The recursion is obviously removed now, but what's the new version do? > > As far as I can tell, it returns a structure like... > > function(...){function(...) {original_function_body(curried_arg, ...=...)}} > > Comparing and contrasting to the version in "functional" package: > 1) quotes work (can do Curry(quote(foo), 2) where the "functional" version > can't) > 2) environment capture works in both constructions > 3) Your new version is exceptionally transparent, as the function body gets > stored so that when you print the body later, you can see the original > > As far as 0 argument functions, I understand the difference, that idea came > from a programming language (q/kdb+) I know that supports a neat compact > syntax for this: > > Suppose in R the function was f(x,y,z) x + y + z > > In q, one could do: > f[1;2] // returns the curried form > f[1;2] each (1 2 3 4 5) // equivalent to Map(function(z) f(1,2,z), 1:5) or > Map(Curry(f, 1, 2), 1:5) > f[1;2;3] // returns 6 > f[1;2][3] // returns 6 I can see why that's useful at the language level, but I think it would be confusing to do so in R. Hadley -- Assistant Professor / Dobelman Family Junior Chair Department of Statistics / Rice University http://had.co.nz/ __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel