[R] Use of ellipsis

Bert Gunter bgunter@4567 @end|ng |rom gm@||@com
Fri May 27 18:41:31 CEST 2022


... and I need to add:
Thank you, Ivan, for correcting my previous false implication that
giving the parent.frame() call as a default or explicitly makes no
difference, as it obviously does (for the reasons I explained ...
correctly, I hope!).

Bert

On Fri, May 27, 2022 at 8:45 AM Bert Gunter <bgunter.4567 using gmail.com> wrote:
>
> 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