This may have been asked before, but is there an elegant way to check
whether an variable/argument passed to a function is a "parse tree"
for an (unevaluated) expression or not, *without* evaluating it if
not?
Currently, I do various rather ad hoc eval()+substitute() tricks for
this that most likely only work under certain circumstances. Ideally,
I'm looking for a isParseTree() function such that I can call:
expr0 <- foo({ x <- 1 })
expr1 <- foo(expr0)
stopifnot(identical(expr1, expr0))
where foo() is:
foo <- function(expr) {
if (!isParseTree(expr))
expr <- substitute(expr)
expr
}
I also want to be able to do:
expr2 <- foo(foo(foo(foo(expr0))))
stopifnot(identical(expr2, expr0))
and calling foo() from within other functions that may use the same
"tricks". The alternative is of course to do:
foo <- function(expr, substitute=TRUE) {
if (substitute) expr <- substitute(expr)
expr
}
but it would be neat to do this without passing an extra argument. If
this is not possible to implement in plain R, can this be done
internally inspecting SEXP:s and so on? Even better would be if
substitute() could do this for me, e.g.
expr <- substitute(expr, unlessAlreadyDone=TRUE)
Any suggestions?
Thanks,
Henrik
How to test if an object/argument is "parse tree" - without evaluating it?
7 messages · Henrik Bengtsson, Duncan Murdoch, Kevin Ushey +3 more
On 01/05/2014, 4:39 PM, Henrik Bengtsson wrote:
This may have been asked before, but is there an elegant way to check whether an variable/argument passed to a function is a "parse tree" for an (unevaluated) expression or not, *without* evaluating it if not?
"Parse tree" isn't R terminology. Could you give an example of one call that passes a parse tree, and one that doesn't? Duncan Murdoch
Currently, I do various rather ad hoc eval()+substitute() tricks for
this that most likely only work under certain circumstances. Ideally,
I'm looking for a isParseTree() function such that I can call:
expr0 <- foo({ x <- 1 })
expr1 <- foo(expr0)
stopifnot(identical(expr1, expr0))
where foo() is:
foo <- function(expr) {
if (!isParseTree(expr))
expr <- substitute(expr)
expr
}
I also want to be able to do:
expr2 <- foo(foo(foo(foo(expr0))))
stopifnot(identical(expr2, expr0))
and calling foo() from within other functions that may use the same
"tricks". The alternative is of course to do:
foo <- function(expr, substitute=TRUE) {
if (substitute) expr <- substitute(expr)
expr
}
but it would be neat to do this without passing an extra argument. If
this is not possible to implement in plain R, can this be done
internally inspecting SEXP:s and so on? Even better would be if
substitute() could do this for me, e.g.
expr <- substitute(expr, unlessAlreadyDone=TRUE)
Any suggestions?
Thanks,
Henrik
______________________________________________ R-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Henrik,
If I understand correctly, you want something along the lines of
(following your example):
foo <- function(expr) {
if (!is.language(expr)) substitute(expr)
else expr
}
## first example
expr0 <- foo({ x <- 1 })
expr1 <- foo(expr0)
stopifnot(identical(expr1, expr0))
## second
expr2 <- foo(foo(foo(foo(expr0))))
stopifnot(identical(expr2, expr0))
Hadley's guide on NSE + language elements in R
(http://adv-r.had.co.nz/Computing-on-the-language.html,
http://adv-r.had.co.nz/Expressions.html) may be helpful here.
Cheers,
Kevin
On Thu, May 1, 2014 at 1:54 PM, Duncan Murdoch <murdoch.duncan at gmail.com> wrote:
On 01/05/2014, 4:39 PM, Henrik Bengtsson wrote:
This may have been asked before, but is there an elegant way to check whether an variable/argument passed to a function is a "parse tree" for an (unevaluated) expression or not, *without* evaluating it if not?
"Parse tree" isn't R terminology. Could you give an example of one call that passes a parse tree, and one that doesn't? Duncan Murdoch
Currently, I do various rather ad hoc eval()+substitute() tricks for
this that most likely only work under certain circumstances. Ideally,
I'm looking for a isParseTree() function such that I can call:
expr0 <- foo({ x <- 1 })
expr1 <- foo(expr0)
stopifnot(identical(expr1, expr0))
where foo() is:
foo <- function(expr) {
if (!isParseTree(expr))
expr <- substitute(expr)
expr
}
I also want to be able to do:
expr2 <- foo(foo(foo(foo(expr0))))
stopifnot(identical(expr2, expr0))
and calling foo() from within other functions that may use the same
"tricks". The alternative is of course to do:
foo <- function(expr, substitute=TRUE) {
if (substitute) expr <- substitute(expr)
expr
}
but it would be neat to do this without passing an extra argument. If
this is not possible to implement in plain R, can this be done
internally inspecting SEXP:s and so on? Even better would be if
substitute() could do this for me, e.g.
expr <- substitute(expr, unlessAlreadyDone=TRUE)
Any suggestions?
Thanks,
Henrik
______________________________________________ R-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
______________________________________________ R-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
This may have been asked before, but is there an elegant way to check whether an variable/argument passed to a function is a "parse tree" for an (unevaluated) expression or not, *without* evaluating it if not?
I doubt it. Some packages say that if the argument is a formula then its right hand side will be used, unevaluated. (You could issue a warning if the formula had a left side.) This offloads the logic to the ~ or formula function. It also has the advantage that environment(formula) tells you where the symbols in the expression should be looked up. Bill Dunlap TIBCO Software wdunlap tibco.com
On Thu, May 1, 2014 at 1:39 PM, Henrik Bengtsson <hb at biostat.ucsf.edu> wrote:
This may have been asked before, but is there an elegant way to check
whether an variable/argument passed to a function is a "parse tree"
for an (unevaluated) expression or not, *without* evaluating it if
not?
Currently, I do various rather ad hoc eval()+substitute() tricks for
this that most likely only work under certain circumstances. Ideally,
I'm looking for a isParseTree() function such that I can call:
expr0 <- foo({ x <- 1 })
expr1 <- foo(expr0)
stopifnot(identical(expr1, expr0))
where foo() is:
foo <- function(expr) {
if (!isParseTree(expr))
expr <- substitute(expr)
expr
}
I also want to be able to do:
expr2 <- foo(foo(foo(foo(expr0))))
stopifnot(identical(expr2, expr0))
and calling foo() from within other functions that may use the same
"tricks". The alternative is of course to do:
foo <- function(expr, substitute=TRUE) {
if (substitute) expr <- substitute(expr)
expr
}
but it would be neat to do this without passing an extra argument. If
this is not possible to implement in plain R, can this be done
internally inspecting SEXP:s and so on? Even better would be if
substitute() could do this for me, e.g.
expr <- substitute(expr, unlessAlreadyDone=TRUE)
Any suggestions?
Thanks,
Henrik
______________________________________________ R-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
On Thu, May 1, 2014 at 4:08 PM, Kevin Ushey <kevinushey at gmail.com> wrote:
Henrik,
If I understand correctly, you want something along the lines of
(following your example):
foo <- function(expr) {
if (!is.language(expr)) substitute(expr)
else expr
}
## first example
expr0 <- foo({ x <- 1 })
expr1 <- foo(expr0)
stopifnot(identical(expr1, expr0))
## second
expr2 <- foo(foo(foo(foo(expr0))))
stopifnot(identical(expr2, expr0))
Unfortunately this won't work in general because is.language evaluates expr:
foo(stop("Uh oh!"))
In general, I'm with Bill Dunlap - you're better off being explicit
with formulas.
Hadley
My take would be that this is barking up the wrong tree. If you want to pass expressions in a way that a function can recognize, use formulas or expression objects. One problem is that pretty much every unevaluated argument is a "parse tree". The only other thing it can be is a constant object, but that is really just the simplest possible parse tree. In what situation exactly were you expecting isParseTree to return FALSE? -pd
On 01 May 2014, at 22:39 , Henrik Bengtsson <hb at biostat.ucsf.edu> wrote:
This may have been asked before, but is there an elegant way to check
whether an variable/argument passed to a function is a "parse tree"
for an (unevaluated) expression or not, *without* evaluating it if
not?
Currently, I do various rather ad hoc eval()+substitute() tricks for
this that most likely only work under certain circumstances. Ideally,
I'm looking for a isParseTree() function such that I can call:
expr0 <- foo({ x <- 1 })
expr1 <- foo(expr0)
stopifnot(identical(expr1, expr0))
where foo() is:
foo <- function(expr) {
if (!isParseTree(expr))
expr <- substitute(expr)
expr
}
I also want to be able to do:
expr2 <- foo(foo(foo(foo(expr0))))
stopifnot(identical(expr2, expr0))
and calling foo() from within other functions that may use the same
"tricks". The alternative is of course to do:
foo <- function(expr, substitute=TRUE) {
if (substitute) expr <- substitute(expr)
expr
}
but it would be neat to do this without passing an extra argument. If
this is not possible to implement in plain R, can this be done
internally inspecting SEXP:s and so on? Even better would be if
substitute() could do this for me, e.g.
expr <- substitute(expr, unlessAlreadyDone=TRUE)
Any suggestions?
Thanks,
Henrik
______________________________________________ R-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Peter Dalgaard, Professor, Center for Statistics, Copenhagen Business School Solbjerg Plads 3, 2000 Frederiksberg, Denmark Phone: (+45)38153501 Email: pd.mes at cbs.dk Priv: PDalgd at gmail.com
Thank you all for great feedback - very helpful. They view was great half way up the tree, but I'll add this one to "It may be possible, but don't do it. Rethink what you're doing". Hadley touches on this in his write up [http://adv-r.had.co.nz/Computing-on-the-language.html#calling-from-another-function].
On Thu, May 1, 2014 at 2:44 PM, peter dalgaard <pdalgd at gmail.com> wrote:
My take would be that this is barking up the wrong tree. If you want to pass expressions in a way that a function can recognize, use formulas or expression objects. One problem is that pretty much every unevaluated argument is a "parse tree". The only other thing it can be is a constant object, but that is really just the simplest possible parse tree. In what situation exactly were you expecting isParseTree to return FALSE?
I guess this (and Duncan's) question is more of a rhetorical kind, which is also what I hoped for, but specifically I wanted to test it on the 'expr0' object as in my example. Thanks, Henrik PS. Duncan, I was trying find a good name for it and got "parse tree" from ?substitute.
-pd On 01 May 2014, at 22:39 , Henrik Bengtsson <hb at biostat.ucsf.edu> wrote:
This may have been asked before, but is there an elegant way to check
whether an variable/argument passed to a function is a "parse tree"
for an (unevaluated) expression or not, *without* evaluating it if
not?
Currently, I do various rather ad hoc eval()+substitute() tricks for
this that most likely only work under certain circumstances. Ideally,
I'm looking for a isParseTree() function such that I can call:
expr0 <- foo({ x <- 1 })
expr1 <- foo(expr0)
stopifnot(identical(expr1, expr0))
where foo() is:
foo <- function(expr) {
if (!isParseTree(expr))
expr <- substitute(expr)
expr
}
I also want to be able to do:
expr2 <- foo(foo(foo(foo(expr0))))
stopifnot(identical(expr2, expr0))
and calling foo() from within other functions that may use the same
"tricks". The alternative is of course to do:
foo <- function(expr, substitute=TRUE) {
if (substitute) expr <- substitute(expr)
expr
}
but it would be neat to do this without passing an extra argument. If
this is not possible to implement in plain R, can this be done
internally inspecting SEXP:s and so on? Even better would be if
substitute() could do this for me, e.g.
expr <- substitute(expr, unlessAlreadyDone=TRUE)
Any suggestions?
Thanks,
Henrik
______________________________________________ R-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
-- Peter Dalgaard, Professor, Center for Statistics, Copenhagen Business School Solbjerg Plads 3, 2000 Frederiksberg, Denmark Phone: (+45)38153501 Email: pd.mes at cbs.dk Priv: PDalgd at gmail.com