How to emulate Lisp's let function in R?

Go To StackoverFlow.com

3

I'm trying to write a let function that allows me to do things like:

let(a=2, b=3, a+b)
>>> 5

Currently I'm stuck with

let <- function(..., expr) {
  with(list(...), quote(expr))
}

which doesn't work at all. Any help appreciated.

2012-04-04 18:35
by Ernest A


11

Here's one way:

let <- function(..., expr) {
    expr <- substitute(expr)
    dots <- list(...)
    eval(expr, dots)
}

let(a = 2, b = 3, expr = a+b)
# [1] 5

Edit: Alternatively, if you don't want to have to name the expression-to-be-evaluated (i.e. passing it in via expr), and if you are certain that it will always be the last argument, you could do something like this.

let <- function(...) {
    args <- as.list(sys.call())[-1]
    n <- length(args)
    eval(args[[n]], args[-n])
}

let(a = 2, b = 3, a + b)
# [1] 5
2012-04-04 18:40
by Josh O'Brien
Thanks. It looks like expr has to be passed as a named argument, otherwise it's captured by ..., right - Ernest A 2012-04-04 19:00
@Ernest: yes. All arguments after ... must be named - Joshua Ulrich 2012-04-04 19:01
@Ernest -- Take a look at the second version of let(), which I just added. I think it may address the question underlying your comment.. - Josh O'Brien 2012-04-04 19:05
...or just put expr first: let <- function(expr, ...) eval(substitute(expr), list(...))Joshua Ulrich 2012-04-04 19:11
@JoshO'Brien: The second version works exactly as I had in mind, thanks - Ernest A 2012-04-04 19:11
@JoshuaUlrich: Nice suggestion, but since expr may be quite long, I think it's better if it's the last argument - Ernest A 2012-04-04 19:13


1

let <- function(a,b, expr=a+b){return(expr)}
let(2,3)
# [1] 5
2012-04-04 18:49
by 42-
Thank you, but this only seems to work with the default expression -- let(a=2,b=3,expr=a-b) gives an error - Ernest A 2012-04-04 19:18
Ads