[Rd] Curry: proposed new functional programming, er, function.

Hadley Wickham hadley at rice.edu
Fri May 25 23:23:59 CEST 2012


On Fri, May 25, 2012 at 3:14 PM, Yike Lu <yikelu.home at 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/



More information about the R-devel mailing list