[Rd] Capturing the expression representing the body of a function
Hi all, What's the preferred way of capturing the expression representing the contents of a function? * body(write.csv) gives me a braced expression * body(write.csv)[-1] gives me a mangled call * as.list(body(write.csv)[-1]) gives me a list of calls * as.expression(as.list(body(write.csv)[-1])) is what I want but seems like too much work Any suggestions? Thanks, 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] Capturing the expression representing the body of a function
On 02/05/2011 3:21 PM, Hadley Wickham wrote: Hi all, What's the preferred way of capturing the expression representing the contents of a function? * body(write.csv) gives me a braced expression * body(write.csv)[-1] gives me a mangled call * as.list(body(write.csv)[-1]) gives me a list of calls * as.expression(as.list(body(write.csv)[-1])) is what I want but seems like too much work Any suggestions? The body of a function isn't an expression, it's a language object. A language object is represented internally as a pairlist, while an expression is represented as a generic vector, i.e. the thing that list() gives. Your 1st try gives you the language object. The other ones only work when the body consists of a call to `{`, as the body of most complex functions does, but not for simple ones like f - function(x) 2*x So I would say your question should be: What's the best way to construct an expression vector s.t. evaluating its elements in order is like evaluating the body of a function? And the answer to that is something like body2expr - function(f) { body - body(f) if (typeof(body) == language identical(body[[1]], quote(`{`))) as.expression(as.list(body[-1])) else as.expression(body) } Duncan Murdoch __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Capturing the expression representing the body of a function
On Mon, May 2, 2011 at 4:11 PM, Duncan Murdoch murdoch.dun...@gmail.com wrote: On 02/05/2011 3:21 PM, Hadley Wickham wrote: Hi all, What's the preferred way of capturing the expression representing the contents of a function? * body(write.csv) gives me a braced expression * body(write.csv)[-1] gives me a mangled call * as.list(body(write.csv)[-1]) gives me a list of calls * as.expression(as.list(body(write.csv)[-1])) is what I want but seems like too much work Any suggestions? The body of a function isn't an expression, it's a language object. A language object is represented internally as a pairlist, while an expression is represented as a generic vector, i.e. the thing that list() gives. Your 1st try gives you the language object. The other ones only work when the body consists of a call to `{`, as the body of most complex functions does, but not for simple ones like f - function(x) 2*x So I would say your question should be: What's the best way to construct an expression vector s.t. evaluating its elements in order is like evaluating the body of a function? And the answer to that is something like body2expr - function(f) { body - body(f) if (typeof(body) == language identical(body[[1]], quote(`{`))) as.expression(as.list(body[-1])) else as.expression(body) } Also try as.expression(as.list(f)[[3]]) e.g. f - function(x, y) { x + y } as.expression(as.list(f)[[3]]) expression({ x + y }) g - function(x, y) x + y as.expression(as.list(g)[[3]]) expression(x + y) -- 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] Capturing the expression representing the body of a function
The body of a function isn't an expression, it's a language object. A language object is represented internally as a pairlist, while an expression is represented as a generic vector, i.e. the thing that list() gives. That doesn't agree with the documentation of is.language which implies a language object is a ‘name’, a ‘call’, or an ‘expression’, and doesn't mention pairlist anywhere. Your 1st try gives you the language object. It gives me a call, doesn't it? And the documentation for body implies that this special type of call is called a bracketed expression (despite it not being an expression as defined in the documentation for expression) (I don't mean to be nit-picky, I'm just trying to understand what's going on) So I would say your question should be: What's the best way to construct an expression vector s.t. evaluating its elements in order is like evaluating the body of a function? And the answer to that is something like body2expr - function(f) { body - body(f) if (typeof(body) == language identical(body[[1]], quote(`{`))) as.expression(as.list(body[-1])) else as.expression(body) } Ok, thanks. 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