[R] Use of ellipsis
Bert Gunter
bgunter@4567 @end|ng |rom gm@||@com
Fri May 27 17:45:03 CEST 2022
I think we're getting confused here. substitute() and quote() are
different. Your original suggestion used substitute(). eval() works
here as intended with the default env argument:
f <- function() {
x <- 'function'
list(qu = eval(quote(x), parent.frame()),
defqu = eval(quote(x)),
sub = eval(substitute(x), parent.frame()),
defsub = eval(substitute(x))
)
> f()
$qu
[1] "caller"
$defqu
[1] "function"
$sub
[1] "function"
$defsub
[1] "function"
}
So, there are 2 separate questions here:
1) What is the difference between substitute() and quote()
2) Why does eval() work differently with quote() with and without the
default 'parent.frame()' argument?
Herewith my understanding. Please **do** correct errors.
1. quote() just quotes its argument. quote(x) := x, (a 'name' language object.)
x is a bound symbol in the default evaluation environment, so
substitute(x) replaces x with its value. Hence eval() does nothing to
it with or without explicitly providing the default.
2. Consider:
g1 <- function() {
x <- 'function'
eval(quote(x))
}
g2 <- function() {
x <- 'function'
eval(quote(x), env= parent.frame())
}
> g1()
[1] "function"
> g2()
[1] "caller"
This looks like to me a case of delayed assignment. In g1, the default
value of parent.frame() is a **promise**, and is not evaluated until
eval() is called, at which time the parent.frame is the environment of
g2, where x = 'function' . In g2, the env argument, parent.frame(),
is explicitly given and so is immediately evaluated in the environment
of g2, whose parent is .GlobalEnv where x lives as the value 'caller'.
HTH (and that I haven't screwed things up),
Bert
Bert Gunter
"The trouble with having an open mind is that people keep coming along
and sticking things into it."
-- Opus (aka Berkeley Breathed in his "Bloom County" comic strip )
On Thu, May 26, 2022 at 11:24 PM Ivan Krylov <krylov.r00t using gmail.com> wrote:
>
> On Thu, 26 May 2022 15:51:38 -0700
> Bert Gunter <bgunter.4567 using gmail.com> wrote:
>
> > FWIW, you don't need to explicitly provide parent.frame() as it's the
> > default of the 'envir' argument of eval anyway.
>
> Unfortunately, there's a difference between evaluating parent.frame()
> explicitly when calling eval() and letting eval() evaluate
> parent.frame() as the default value of the envir argument. What I could
> have used here is eval.parent():
>
> x <- 'caller'
> f <- function() {
> x <- 'function'
> list(
> eval = eval(quote(x)),
> explicit.parent = eval(quote(x), parent.frame()),
> eval.parent = eval.parent(quote(x))
> )
> }
> f()
> # $eval
> # [1] "function"
> #
> # $explicit.parent
> # [1] "caller"
> #
> # $eval.parent
> # [1] "caller"
>
> --
> Best regards,
> Ivan
More information about the R-help
mailing list