[Rd] Capturing the expression representing the body of a function

2011-05-02 Thread Hadley Wickham
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

2011-05-02 Thread Duncan Murdoch

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

2011-05-02 Thread Gabor Grothendieck
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

2011-05-02 Thread Hadley Wickham
 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