Re: [Rd] Curry: proposed new functional programming, er, function.
I just realized that even in the non-nested case, calling from top level broke some of my code inexplicably, since the globally stored function call gets overridden if you call Curry again. So old Curried functions break. Glad to have this fix. On 5/25/2012 5:23 PM, Hadley Wickham wrote: 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. __ 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 5/25/12 5:23 PM, Hadley Wickham wrote: On Fri, May 25, 2012 at 3:14 PM, Yike Luyikelu.h...@gmail.com 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. Yes I could see how one would do that - if the match.call detects a Curry as the first function being called, we would short circuit the usual evaluation into a different path which properly collapses all the nesting. It's interesting how R offers these facilities to override the usual evaluation order, but if one does that too much it could easily become confusing. I was looking at Rpipe the other day (https://github.com/slycoder/Rpipe) and the way he implements it is by defining his own Eval. Cheers, __ 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 Sat, May 26, 2012 at 12:30 PM, Yike Lu yikelu.h...@gmail.com wrote: On 5/25/12 5:23 PM, Hadley Wickham wrote: On Fri, May 25, 2012 at 3:14 PM, Yike Luyikelu.h...@gmail.com 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. Yes I could see how one would do that - if the match.call detects a Curry as the first function being called, we would short circuit the usual evaluation into a different path which properly collapses all the nesting. It's interesting how R offers these facilities to override the usual evaluation order, but if one does that too much it could easily become confusing. I was looking at Rpipe the other day (https://github.com/slycoder/Rpipe) and the way he implements it is by defining his own Eval. The proto package does currying on proto methods by defining $.proto appropriately: library(proto) p - proto(a = 1, b = 2) # same as ls(p) - output is c(a, b) p$ls() Here ls() is _not_ a special proto method but is just the ordinary ls() provided by R. $.proto calls ls() sticking in p as the first argument. A proto object is an environment and ls with a first argument that is an environment lists the names of the objects in that environment. Similarly: p$as.list() p$str() p$parent.env() p$print() p$eapply(length) are the same as as.list(p), str(p), parent.env(p), print(p) and eapply(p, length). Although this might seem like its just syntax in proto it does allow one to override the method. For example, p2 - proto(a = 1, b = 2, print = function(.) with(., cat(a:, a, b:, b, \n)) ) p2$print() # uses p2's print print(p2) # uses R's print etc. -- Statistics Software Consulting GKX Group, GKX Associates Inc. tel: 1-877-GKX-GROUP email: ggrothendieck at gmail.com __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
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
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] Curry: proposed new functional programming, er, function.
On Fri, May 25, 2012 at 3:14 PM, Yike Lu yikelu.h...@gmail.com 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
Re: [Rd] Curry: proposed new functional programming, er, function.
Hadley Wickham-2 wrote 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 - as.name(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 } But I've probably forgotten something else. Hopefully Luke will chime in if I'm proceeding down a path that can never be made to work completely correctly. 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). 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). -- View this message in context: http://r.789695.n4.nabble.com/Curry-proposed-new-functional-programming-er-function-tp917654p4631127.html Sent from the R devel mailing list archive at Nabble.com. __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Curry: proposed new functional programming, er, function.
Sharpie wrote: Currently, the only Curry implementation I know of is in the roxygen package which is kind of a weird dependency to install just for this one function. I end up using Curry so much outside of Roxygen that I spun it off into the `functional' package: https://r-forge.r-project.org/projects/functional/ Compose is there, too, and a couple other superfluous things. __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Curry: proposed new functional programming, er, function.
Thanks, Hadley. This (i.e., different ways to prepare curry) is quite instructive to me. The following update makes the generated function look a little nicer if you pass in the name of a function: Curry - function(FUN, ...) { args - match.call(expand.dots = FALSE)$... args$... - as.name(...) if (is.name(FUN)) { fname - FUN } else if (is.character(FUN)) { fname - as.name(FUN) } else { fname - as.name(FUN) } curry_call - as.call(c(list(fname), args)) eval(call(function, as.pairlist(alist(... = )), curry_call)) } And it seems to work ok in terms of preserving evaluation (I can't how it could be any different to making the anonymous function yourself, unless I've missed something subtle with environments and scoping) hadley - 1:10 plothadley - Curry(plot, x = hadley) plothadley function (...) plot(x = hadley, ... = ...) environment: 0x1031d7c00 plothadley() plothadley(runif(10)) The only (minor) problem is that I couldn't figure out how to construct the interior call to yield plot(x = hadley, ...) 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
Re: [Rd] Curry: proposed new functional programming, er, function.
And it seems to work ok in terms of preserving evaluation (I can't how it could be any different to making the anonymous function yourself, unless I've missed something subtle with environments and scoping) Which indeed I have. Hmmm, need to think about this more. 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
Re: [Rd] Curry: proposed new functional programming, er, function.
I thought I might bring this up again - it now seems like Curry would be a natural fit with Reduce, Filter, Find, Map, Negate and Position. Any chance we might see this in a future version of R? Hadley On Thu, Nov 1, 2007 at 2:00 PM, Byron Ellis byron.el...@gmail.com wrote: Hi all (especially R-core) I suppose, With the introduction of the new functional programming functions into base I thought I'd ask for a Curry() function. I use a simple one that looks this: Curry = function(FUN,...) { .orig = list(...);function(...) do.call(FUN,c(.orig,list(...))) } This comes in really handy when using say, heatmap(): heatmap(mydata,hclustfun=Curry(hclust,method=average)) or other functions where there are ... arguments, but it's not clear where they should end up. -- Byron Ellis (byron.el...@gmail.com) Oook -- The Librarian __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel -- 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
Re: [Rd] Curry: proposed new functional programming, er, function.
I too would like this (being an Indian!). Here is an example that came up just yesterday with regards to solving a quadrature problem using the cubature package. The adaptIntegrate function does not allow additional arguments via ... Uwe suggested a work around, but `Curry' would solve it nicely (and it also tastes better!): Curry = function(FUN,...) { .orig = list(...) function(...) do.call(FUN,c(.orig, list(...))) } require(cubature) f - function(x, a) cos(2*pi*x*a) # a simple test function # this works a - 0.2 adaptIntegrate(function(x, argA=a) f(x, a=argA), lower=0, upper=2) # but this doesn't work rm(a) adaptIntegrate(function(x, argA=a) f(x, a=argA), lower=0, upper=2, a=0.2) # Use of Curry adaptIntegrate(Curry(f, a=0.2), lower=0, upper=2) Best, Ravi. --- Ravi Varadhan, Ph.D. Assistant Professor, Division of Geriatric Medicine and Gerontology School of Medicine Johns Hopkins University Ph. (410) 502-2619 email: rvarad...@jhmi.edu -Original Message- From: r-devel-boun...@r-project.org [mailto:r-devel-boun...@r-project.org] On Behalf Of Hadley Wickham Sent: Wednesday, May 04, 2011 10:29 AM To: Byron Ellis Cc: R Development Mailing List Subject: Re: [Rd] Curry: proposed new functional programming, er, function. I thought I might bring this up again - it now seems like Curry would be a natural fit with Reduce, Filter, Find, Map, Negate and Position. Any chance we might see this in a future version of R? Hadley On Thu, Nov 1, 2007 at 2:00 PM, Byron Ellis byron.el...@gmail.com wrote: Hi all (especially R-core) I suppose, With the introduction of the new functional programming functions into base I thought I'd ask for a Curry() function. I use a simple one that looks this: Curry = function(FUN,...) { .orig = list(...);function(...) do.call(FUN,c(.orig,list(...))) } This comes in really handy when using say, heatmap(): heatmap(mydata,hclustfun=Curry(hclust,method=average)) or other functions where there are ... arguments, but it's not clear where they should end up. -- Byron Ellis (byron.el...@gmail.com) Oook -- The Librarian __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel -- 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 __ 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 04/05/2011 10:40 AM, Ravi Varadhan wrote: I too would like this (being an Indian!). Here is an example that came up just yesterday with regards to solving a quadrature problem using the cubature package. The adaptIntegrate function does not allow additional arguments via ... Uwe suggested a work around, but `Curry' would solve it nicely (and it also tastes better!): Curry = function(FUN,...) { .orig = list(...) function(...) do.call(FUN,c(.orig, list(...))) } require(cubature) f- function(x, a) cos(2*pi*x*a) # a simple test function # this works a- 0.2 adaptIntegrate(function(x, argA=a) f(x, a=argA), lower=0, upper=2) # but this doesn't work rm(a) adaptIntegrate(function(x, argA=a) f(x, a=argA), lower=0, upper=2, a=0.2) # Use of Curry adaptIntegrate(Curry(f, a=0.2), lower=0, upper=2) Two objections: 1. I don't see how that is preferable to adaptIntegrate(function(x) f(x, a=0.2), lower=0, upper=2) 2. There seems to be confusion about what currying means. The Wikipedia page http://en.wikipedia.org/wiki/Currying indicates that the function Curry() defined above is really doing partial function application, not currying. I'm in no position to judge whether Byron got it right or Wikipedia did, but this suggests to me that the name Curry is inappropriate, since at least some people who know what currying is would not guess that it does what it does. Duncan Murdoch Best, Ravi. --- Ravi Varadhan, Ph.D. Assistant Professor, Division of Geriatric Medicine and Gerontology School of Medicine Johns Hopkins University Ph. (410) 502-2619 email: rvarad...@jhmi.edu -Original Message- From: r-devel-boun...@r-project.org [mailto:r-devel-boun...@r-project.org] On Behalf Of Hadley Wickham Sent: Wednesday, May 04, 2011 10:29 AM To: Byron Ellis Cc: R Development Mailing List Subject: Re: [Rd] Curry: proposed new functional programming, er, function. I thought I might bring this up again - it now seems like Curry would be a natural fit with Reduce, Filter, Find, Map, Negate and Position. Any chance we might see this in a future version of R? Hadley On Thu, Nov 1, 2007 at 2:00 PM, Byron Ellisbyron.el...@gmail.com wrote: Hi all (especially R-core) I suppose, With the introduction of the new functional programming functions into base I thought I'd ask for a Curry() function. I use a simple one that looks this: Curry = function(FUN,...) { .orig = list(...);function(...) do.call(FUN,c(.orig,list(...))) } This comes in really handy when using say, heatmap(): heatmap(mydata,hclustfun=Curry(hclust,method=average)) or other functions where there are ... arguments, but it's not clear where they should end up. -- Byron Ellis (byron.el...@gmail.com) Oook -- The Librarian __ 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 Wed, May 4, 2011 at 10:40 AM, Ravi Varadhan rvarad...@jhmi.edu wrote: I too would like this (being an Indian!). Here is an example that came up just yesterday with regards to solving a quadrature problem using the cubature package. The adaptIntegrate function does not allow additional arguments via ... Uwe suggested a work around, but `Curry' would solve it nicely (and it also tastes better!): Curry = function(FUN,...) { .orig = list(...) function(...) do.call(FUN,c(.orig, list(...))) } require(cubature) f - function(x, a) cos(2*pi*x*a) # a simple test function # this works a - 0.2 adaptIntegrate(function(x, argA=a) f(x, a=argA), lower=0, upper=2) # but this doesn't work rm(a) adaptIntegrate(function(x, argA=a) f(x, a=argA), lower=0, upper=2, a=0.2) # Use of Curry adaptIntegrate(Curry(f, a=0.2), lower=0, upper=2) Here is another approach. If we preface any function with gsubfn's fn$ then it will turn formulas (subject to certain rules to determine which to pay attention to) into functions. 1. Here it is applied to the cubature example library(cubature) library(gsubfn) Loading required package: proto fn$adaptIntegrate(~ f(x, 0.2), lower=0, upper=2) $integral [1] 0.4677446 $error [1] 1.247382e-14 $functionEvaluations [1] 15 $returnCode [1] 0 2. and here is the heatmap example redone. The example line is to compute x so that the code is self contained: library(gsubfn) example(heatmap) fn$heatmap(x, hclustfun = ~ hclust(x, method=average)) -- Statistics Software Consulting GKX Group, GKX Associates Inc. tel: 1-877-GKX-GROUP email: ggrothendieck at gmail.com __ 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 Wed, 4 May 2011, Ravi Varadhan wrote: I too would like this (being an Indian!). I would not. Here is an example that came up just yesterday with regards to solving a quadrature problem using the cubature package. The adaptIntegrate function does not allow additional arguments via ... Uwe suggested a work around, but `Curry' would solve it nicely (and it also tastes better!): Curry = function(FUN,...) { .orig = list(...) function(...) do.call(FUN,c(.orig, list(...))) } This has quite different behavior with respect to evaluation/lazy evaluation than an analogous anonymous function. In addition, do.call has some fairly strange aspect so it with respect to how it intereacts with sys.xyz functions, and does not do what you want in many cases I care about when quote = FALSE, as is the default. Adding this would create more problems than is solves. require(cubature) f - function(x, a) cos(2*pi*x*a) # a simple test function # this works a - 0.2 adaptIntegrate(function(x, argA=a) f(x, a=argA), lower=0, upper=2) Yes -- as do a number of other variations. # but this doesn't work rm(a) adaptIntegrate(function(x, argA=a) f(x, a=argA), lower=0, upper=2, a=0.2) Of course not -- why would anyone think it would? # Use of Curry adaptIntegrate(Curry(f, a=0.2), lower=0, upper=2) The _concept_ of currying is useful, and maybe more can be done to provide guidance and education on how to do it, but adding a function that sometimes works and somesimes does surprising things is not the way to go. Best, luke Best, Ravi. --- Ravi Varadhan, Ph.D. Assistant Professor, Division of Geriatric Medicine and Gerontology School of Medicine Johns Hopkins University Ph. (410) 502-2619 email: rvarad...@jhmi.edu -Original Message- From: r-devel-boun...@r-project.org [mailto:r-devel-boun...@r-project.org] On Behalf Of Hadley Wickham Sent: Wednesday, May 04, 2011 10:29 AM To: Byron Ellis Cc: R Development Mailing List Subject: Re: [Rd] Curry: proposed new functional programming, er, function. I thought I might bring this up again - it now seems like Curry would be a natural fit with Reduce, Filter, Find, Map, Negate and Position. Any chance we might see this in a future version of R? Hadley On Thu, Nov 1, 2007 at 2:00 PM, Byron Ellis byron.el...@gmail.com wrote: Hi all (especially R-core) I suppose, With the introduction of the new functional programming functions into base I thought I'd ask for a Curry() function. I use a simple one that looks this: Curry = function(FUN,...) { .orig = list(...);function(...) do.call(FUN,c(.orig,list(...))) } This comes in really handy when using say, heatmap(): heatmap(mydata,hclustfun=Curry(hclust,method=average)) or other functions where there are ... arguments, but it's not clear where they should end up. -- Byron Ellis (byron.el...@gmail.com) Oook -- The Librarian __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel -- Luke Tierney Statistics and Actuarial Science Ralph E. Wareham Professor of Mathematical Sciences University of Iowa Phone: 319-335-3386 Department of Statistics andFax: 319-335-3017 Actuarial Science 241 Schaeffer Hall email: l...@stat.uiowa.edu Iowa City, IA 52242 WWW: http://www.stat.uiowa.edu __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Curry: proposed new functional programming, er, function.
# Use of Curry adaptIntegrate(Curry(f, a=0.2), lower=0, upper=2) The _concept_ of currying is useful, and maybe more can be done to provide guidance and education on how to do it, but adding a function that sometimes works and somesimes does surprising things is not the way to go. What about an alternative approach? Curry - function(FUN, ...) { args - match.call(expand.dots = FALSE)$... args$... - as.name(...) curry_call - as.call(c(list(as.name(FUN)), args)) function(...) { eval(curry_call) } } Or maybe Curry - function(FUN, ...) { args - match.call(expand.dots = FALSE)$... args$... - as.name(...) curry_call - as.call(c(list(as.name(FUN)), args)) eval(bquote(function(...) .(curry_call))) } I think this is pretty close to what you'd get if you made an anonymous function (but I'm probably missing something) 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
Re: [Rd] Curry: proposed new functional programming, er, function.
# Use of Curry adaptIntegrate(Curry(f, a=0.2), lower=0, upper=2) Two objections: 1. I don't see how that is preferable to adaptIntegrate(function(x) f(x, a=0.2), lower=0, upper=2) It's less typing? A more helpful use is when you have a list of functions: funs - list( sum = sum, mean = mean, median = median ) with Curry function you can do : funs2 - lapply(funs, Curry, na.rm = TRUE) as opposed to funs2 - list( sum = function(x, ...) sum(x, ..., na.rm = TRUE), mean = function(x, ...) mean(x, ..., na.rm = TRUE), median = function(x, ...) median(x, ..., na.rm = TRUE) ) 2. There seems to be confusion about what currying means. The Wikipedia page http://en.wikipedia.org/wiki/Currying indicates that the function Curry() defined above is really doing partial function application, not currying. I'm in no position to judge whether Byron got it right or Wikipedia did, but this suggests to me that the name Curry is inappropriate, since at least some people who know what currying is would not guess that it does what it does. I'm not completely sure that discussion is canonical: wikipedia citing a blog post does not a precedent make. I agree the distinction is sensible, but I think the partial function application sense of currying is standard enough that it would cause much confusion. We are not claiming that R has low-level currying, we're creating a function to simulate a useful property of currying. 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
Re: [Rd] Curry: proposed new functional programming, er, function.
Or maybe Curry - function(FUN, ...) { args - match.call(expand.dots = FALSE)$... args$... - as.name(...) curry_call - as.call(c(list(as.name(FUN)), args)) eval(bquote(function(...) .(curry_call))) } Or one more approach: Curry - function(FUN, ...) { args - match.call(expand.dots = FALSE)$... args$... - as.name(...) curry_call - as.call(c(list(as.name(FUN)), args)) eval(call(function, as.pairlist(alist(... = )), curry_call)) } I'm not sure if there's a canonical way of programmatically creating functions. 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
Re: [Rd] Curry: proposed new functional programming, er, function.
Byron Ellis-2 wrote: Hi all (especially R-core) I suppose, With the introduction of the new functional programming functions into base I thought I'd ask for a Curry() function. I use a simple one that looks this: Curry = function(FUN,...) { .orig = list(...);function(...) do.call(FUN,c(.orig,list(...))) } ... I would like to see this as well---it is one of the functional programming constructs I really miss in R after playing with languages like Haskell. Currently, the only Curry implementation I know of is in the roxygen package which is kind of a weird dependency to install just for this one function. -Charlie - Charlie Sharpsteen Undergraduate-- Environmental Resources Engineering Humboldt State University -- View this message in context: http://r.789695.n4.nabble.com/Curry-proposed-new-functional-programming-er-function-tp917654p3496226.html Sent from the R devel mailing list archive at Nabble.com. __ 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 Wed, May 4, 2011 at 1:11 PM, Sharpie ch...@sharpsteen.net wrote: Currently, the only Curry implementation I know of is in the roxygen package which is kind of a weird dependency to install just for this one function. Not entirely comparable but the proto package supports currying of proto arguments. For example, p$ls returns an instantiatedProtoMethod which is an S3 subclass of function that is like the original method but with the first argument filled in: library(proto) p - proto(x = 1) p$ls() [1] x -- Statistics Software Consulting GKX Group, GKX Associates Inc. tel: 1-877-GKX-GROUP email: ggrothendieck at gmail.com __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Curry: proposed new functional programming, er, function.
Thanks, Hadley. This (i.e., different ways to prepare curry) is quite instructive to me. Best, Ravi. --- Ravi Varadhan, Ph.D. Assistant Professor, Division of Geriatric Medicine and Gerontology School of Medicine Johns Hopkins University Ph. (410) 502-2619 email: rvarad...@jhmi.edu -Original Message- From: h.wick...@gmail.com [mailto:h.wick...@gmail.com] On Behalf Of Hadley Wickham Sent: Wednesday, May 04, 2011 12:01 PM To: Duncan Murdoch Cc: Ravi Varadhan; Byron Ellis; R Development Mailing List Subject: Re: [Rd] Curry: proposed new functional programming, er, function. # Use of Curry adaptIntegrate(Curry(f, a=0.2), lower=0, upper=2) Two objections: 1. I don't see how that is preferable to adaptIntegrate(function(x) f(x, a=0.2), lower=0, upper=2) It's less typing? A more helpful use is when you have a list of functions: funs - list( sum = sum, mean = mean, median = median ) with Curry function you can do : funs2 - lapply(funs, Curry, na.rm = TRUE) as opposed to funs2 - list( sum = function(x, ...) sum(x, ..., na.rm = TRUE), mean = function(x, ...) mean(x, ..., na.rm = TRUE), median = function(x, ...) median(x, ..., na.rm = TRUE) ) 2. There seems to be confusion about what currying means. The Wikipedia page http://en.wikipedia.org/wiki/Currying indicates that the function Curry() defined above is really doing partial function application, not currying. I'm in no position to judge whether Byron got it right or Wikipedia did, but this suggests to me that the name Curry is inappropriate, since at least some people who know what currying is would not guess that it does what it does. I'm not completely sure that discussion is canonical: wikipedia citing a blog post does not a precedent make. I agree the distinction is sensible, but I think the partial function application sense of currying is standard enough that it would cause much confusion. We are not claiming that R has low-level currying, we're creating a function to simulate a useful property of currying. 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
Re: [Rd] Curry: proposed new functional programming, er, function.
Hi, On 5 May 2011 02:56, Duncan Murdoch murdoch.dun...@gmail.com wrote: On 04/05/2011 10:40 AM, Ravi Varadhan wrote: I too would like this (being an Indian!). Here is an example that came up just yesterday with regards to solving a quadrature problem using the cubature package. The adaptIntegrate function does not allow additional arguments via ... Uwe suggested a work around, but `Curry' would solve it nicely (and it also tastes better!): Curry = function(FUN,...) { .orig = list(...) function(...) do.call(FUN,c(.orig, list(...))) } require(cubature) f- function(x, a) cos(2*pi*x*a) # a simple test function # this works a- 0.2 adaptIntegrate(function(x, argA=a) f(x, a=argA), lower=0, upper=2) # but this doesn't work rm(a) adaptIntegrate(function(x, argA=a) f(x, a=argA), lower=0, upper=2, a=0.2) # Use of Curry adaptIntegrate(Curry(f, a=0.2), lower=0, upper=2) Two objections: 1. I don't see how that is preferable to adaptIntegrate(function(x) f(x, a=0.2), lower=0, upper=2) In this particular case I don't think it is. The reason I proposed it yesterday for the cubature example was that in some cases it can make the code more concise and clearer in my opinion. This is the case when you override a considerable number of arguments in a function. Consider this, read.table2 = Curry(read.table, header = TRUE, na.strings = , colClasses = numeric, nrows = 23) vs read.table2 = function(..., header = TRUE, na.strings = , colClasses = numeric, nrows = 23) { read.table(header = header, na.strings = na.strings, colClasses = colClasses, nrows = nrows, ...) } Whether or not this should be called curry, I have no idea. In any case it seems like a useful function to have in a base package, regardless of its implementation details. baptiste 2. There seems to be confusion about what currying means. The Wikipedia page http://en.wikipedia.org/wiki/Currying indicates that the function Curry() defined above is really doing partial function application, not currying. I'm in no position to judge whether Byron got it right or Wikipedia did, but this suggests to me that the name Curry is inappropriate, since at least some people who know what currying is would not guess that it does what it does. Duncan Murdoch Best, Ravi. --- Ravi Varadhan, Ph.D. Assistant Professor, Division of Geriatric Medicine and Gerontology School of Medicine Johns Hopkins University Ph. (410) 502-2619 email: rvarad...@jhmi.edu -Original Message- From: r-devel-boun...@r-project.org [mailto:r-devel-boun...@r-project.org] On Behalf Of Hadley Wickham Sent: Wednesday, May 04, 2011 10:29 AM To: Byron Ellis Cc: R Development Mailing List Subject: Re: [Rd] Curry: proposed new functional programming, er, function. I thought I might bring this up again - it now seems like Curry would be a natural fit with Reduce, Filter, Find, Map, Negate and Position. Any chance we might see this in a future version of R? Hadley On Thu, Nov 1, 2007 at 2:00 PM, Byron Ellisbyron.el...@gmail.com wrote: Hi all (especially R-core) I suppose, With the introduction of the new functional programming functions into base I thought I'd ask for a Curry() function. I use a simple one that looks this: Curry = function(FUN,...) { .orig = list(...);function(...) do.call(FUN,c(.orig,list(...))) } This comes in really handy when using say, heatmap(): heatmap(mydata,hclustfun=Curry(hclust,method=average)) or other functions where there are ... arguments, but it's not clear where they should end up. -- Byron Ellis (byron.el...@gmail.com) Oook -- The Librarian __ 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 __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
[Rd] Curry: proposed new functional programming, er, function.
Hi all (especially R-core) I suppose, With the introduction of the new functional programming functions into base I thought I'd ask for a Curry() function. I use a simple one that looks this: Curry = function(FUN,...) { .orig = list(...);function(...) do.call(FUN,c(.orig,list(...))) } This comes in really handy when using say, heatmap(): heatmap(mydata,hclustfun=Curry(hclust,method=average)) or other functions where there are ... arguments, but it's not clear where they should end up. -- Byron Ellis ([EMAIL PROTECTED]) Oook -- The Librarian __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel