Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
No, we are not talking about dinner, although this post is giving me ideas about what I should have for lunch.
To read about what function currying actually means, please see the Wikipedia page. (And while you are there, make a donation already!)
Basically, you take a function of multiple arguments and reduce it to a function with one argument. I probably use the term incorrectly, because I also consider currying to cover any reduction in the number of function arguments, not just down to one.
Here’s an example. I’m using the curry
function
from my personal R package.
library(alrtools) my_rnorm <- curry(rnorm, mean = 100, sd = 200) print(my_rnorm) ## function (n, mean = 100, sd = 200) ## .Call(C_rnorm, n, mean, sd) ## <environment: namespace:stats>
Now, every time I use my_rnorm
the parameters
mean
and sd
are pre-set.
set.seed(95) x <- my_rnorm(100e3) mean(x) ## [1] 99.52828 sd(x) ## [1] 199.7653
NOTE: my curry
function still get a weird error with some functions
that are very general in the arguments they accept, like max
and sum
.
I’m still figuring that out.
There are other packages in R that support currying.
Namely functional
.
library(functional) f_rnorm <- Curry(rnorm, mu = -20, sd = 35) print(f_rnorm) ## function (...) ## do.call(FUN, c(.orig, list(...))) ## <environment: 0x0000000018982178>
Peter Danenberg, the author of the functional
package,
credits Byron Ellis
for the functional::Curry
function.
I have an older version of alrtools:::curry_v1
that I copied from the same source. Fun times.
So, if this has existed since 2007,
why am I blogging about it?
Because I finally solved something annoying about Curry
and I just can’t wait to share (with the two people who will read this).
Check out the function signatures for the two curried functions and the original:
args(f_rnorm) ## function (...) args(my_rnorm) ## function (n, mean = 100, sd = 200) args(rnorm) ## function (n, mean = 0, sd = 1)
f_rnorm
doesn’t tell you anything about the arguments that are left,
or the defaults that were set in the currying process.
Most of the time, no one cares because you just created the curried function
so why should you have forgotten the details about it?
Yes, true, but I want to use alrtools::curry
to provide code for other
people to use, and they might like the visual cues.
Here are some cool things about my new version of curry
- The function signature shows all arguments
- Currying changes the function signature and simply includes defaults for the curried arguments
- You can add new arguments that before were not in the signature!
- You can override the curried arguments if you want (because the currying is done by specifying default values instead of storing the default values in the closure)
- The new function stays in the namespace of the original function, but is still listed in the global environment
- But, remember the caveat I gave above – I am still working through all the issues with
dots
- I haven’t tested this yet, but I am pretty sure that curried arguments will be able to reference other arguments, like in the function signature of
dgamma
Just a note for those of you who like this topic but would rather use
a more reputable package, like functional
. You can still get at
all the information you want within the function closure.
R let’s you examine those, and I will show you how.
(Also, my package is licensed as CC0, so you can steal the code
and use it wherever you want, too. I don’t care. Attribution is nice.)
max100 <- functional::Curry(max, 100) max100(c(40, 20, -21)) ## [1] 100 max100(150, 34, -132) ## [1] 150 ls(environment(max100), all.names = TRUE) ## [1] "..." ".orig" "FUN" environment(max100)$.orig ## [[1]] ## [1] 100 environment(max100)$FUN ## function (..., na.rm = FALSE) .Primitive("max")
Thanks for reading!
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.