From murdoch.duncan at gmail.com  Wed Oct  3 16:26:39 2012
From: murdoch.duncan at gmail.com (Duncan Murdoch)
Date: Wed, 03 Oct 2012 10:26:39 -0400
Subject: [Rd] Creating functions programmatically
In-Reply-To: <CABdHhvH9Q3L16aCQPg=Tn5N+GqJTDW2vhf3=y6_DYcUOXwYvmQ@mail.gmail.com>
References: <CABdHhvH9Q3L16aCQPg=Tn5N+GqJTDW2vhf3=y6_DYcUOXwYvmQ@mail.gmail.com>
Message-ID: <506C4B1F.3070403@gmail.com>

On 03/10/2012 10:16 AM, Hadley Wickham wrote:
> Hi all,
>
> A function has three components: arguments, body and environment. Is
> there no base function that allows us to create a function from those
> three components?

There is:  it is `function`.  The parser converts your function 
definitions into a call to it.  (It has 3 arguments: the formals, the 
body, and the srcref.  The environment is added when it is evaluated.)

So your make_function below is pretty similar (but because `function` is 
primitive, some of the evaluation rules might be different).

Duncan Murdoch

> The best I could come up with is:
>
> make_function <- function(args, body, env = parent.frame()) {
>    args <- as.pairlist(args)
>    stopifnot(is.language(body))
>    f <- eval(call("function", args, body))
>    environment(f) <- env
>    f
> }
> mquote <- function(...) as.list(substitute(list(...))[-1])
>
> add <- make_function(mquote(a = 1, b = a), quote(a + b))
> add(1)
> add(1, 2)
>
> add2 <- make_function(mquote(a = 1, b = a), quote(a + b + d))
> d <- 3
> add2(1)
>
> Am I missing a built in way to do this?  Also, is there a built in
> equivalent to my mquote (= multiquote, for producing a named list of
> quoted inputs)?
>
> Thanks!
>
> Hadley
>



[Rd] Creating functions programmatically
Duncan Murdoch