On 13-02-16 10:22 AM, Hadley Wickham wrote:
This is a little tricky for the deparser.  It sees a call to a function
which was determined by an expression.  Sometimes you want parens, sometimes
you don't.  For example, if getfun(y) returns a function, it's clearer to
display a call as getfun(y)(x) than (getfun(y))(x).

I'll see if I can work out which kinds of expressions need to be
parenthesized and implement it in the deparser.

I suspect it's only when you have a function in the quoted call, not a symbol:

# Don't add parens
q1 <- quote(g(f)(x))
is.symbol(q1[[1]])

# Add parents
q2 <- substitute(f(x), list(f = function(x) {x + 1}))
is.function(q2[[1]])

Thanks for thinking about it!

It's in place now.  There are two kinds of cases it handles:

Unevaluated expressions are the hardest. For those, parens are used when the function is an infix operator other than ::, :::, $, [ or [[.
They're also used for special syntax, like if, while, etc.

For evaluated things, only your example (a closure object) get parens.

I'm sure you can construct things that deparse improperly, but it does a better job now. For example, from the new test script:

> ## Anonymous function calls were not deparsed properly
> substitute(f(x), list(f = function(x) x + 1))
(function (x)
x + 1)(x)
> substitute(f(x), list(f = quote(function(x) x + 1)))
(function(x) x + 1)(x)
> substitute(f(x), list(f = quote(f+g)))
(f + g)(x)
> substitute(f(x), list(f = quote(base::mean)))
base::mean(x)
> substitute(f(x), list(f = quote(a[n])))
a[n](x)
> substitute(f(x), list(f = quote(g(y))))
g(y)(x)
> ## The first three need parens, the last three don't.
>

This is in R-devel and R-patched.

Duncan Murdoch

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to