I think you are looking for eval(quote(x), ...) or evalq(x, ...) . Those do what you expect. The code you show evaluates x before eval even gets a chance to deal with it.
On Nov 13, 2007 9:48 AM, Joerg van den Hoff <[EMAIL PROTECTED]> wrote: > > On Tue, Nov 13, 2007 at 09:04:25AM -0500, Duncan Murdoch wrote: > > On 11/13/2007 8:39 AM, Joerg van den Hoff wrote: > > >my understanding of `eval' behaviour is obviously > > >incomplete. > > > > > >my question: usually `eval(expr)' and `eval(expr, > > >envir=parent.frame())' should be identical. why does the > > >last `eval' (yielding `r3') in this code _not_ evaluate in > > >the local environment of function `f' but rather in the > > >global environment (if `f' is called from there)?] > > > > Because you said "parent.frame()" as its value. The values of > > explicitly passed arguments are evaluated in the frame of the caller, > > i.e. in the evaluation frame of f(). There, parent.frame() is the frame > > that called f(), i.e. the global environment. > > > > Default values for parameters are evaluated in the evaluation frame of > > the function using them. So if you don't specify envir in a call to > > eval(), parent.frame() is evaluated in the eval evaluation frame, and it > > refers to whatever function called eval(). > > > > > > > >#---------------------------------------------------------- > > >f <- function () { > > > > > > a <- 1 > > > x <- 1 > > > > > > model <- y ~ a * x > > > fitfunc <- deriv(model[[3]], c("a"), c("a", "x")) > > > call.fitfunc <- c(list(fitfunc), as.name("a"), as.name("x")) > > > call.fitfunc <- as.call(call.fitfunc) > > > > > > curenv <- environment() > > > > > > cat(" eval(call.fitfunc)\n") > > > r1 = eval(call.fitfunc) > > > str(r1) > > > > > > cat(" eval(call.fitfunc, envir = curenv)\n") > > > r2 = eval(call.fitfunc, envir = curenv) > > > str(r2) > > > > > > cat(" eval(call.fitfunc, envir = parent.frame())\n") > > > r3 = eval(call.fitfunc, envir = parent.frame()) > > > str(r3) > > > > > >} > > >#---------------------------------------------------------- > > > > > > > > >`args(eval)' yields: > > > > > >"function (expr, envir = parent.frame(), enclos = if (is.list(envir) || > > > is.pairlist(envir)) parent.frame() else baseenv())" > > > > > > > > >and the manpage says the same: the default value of `envir' > > >is `parent.frame()'. so I would expect (lazy evaluation) > > >that providing the default argument explicitely should'nt > > >alter the behaviour. where is my error? > > > > Lazy evaluation affects the order of evaluation, but not the evaluation > > environment. If you pass an argument to a function, it will be > > evaluated in your environment. If you rely on the function to provide a > > default, that will be evaluated in the environment of the function. > > OK, I see (and it's probably all in the documentation > somewhere). it's obvious once it's explained. but why _does_ > the following work? > > #-------------------------------------------- > f <- function () { > > x <- 1 > > curenv <- environment() > > cat(" eval(x)\n") > r1 = eval(x) > str(r1) > > cat(" eval(x, envir = curenv\n") > r2 = eval(x, envir = curenv) > str(r2) > > cat(" eval(x, envir = parent.frame())\n") > r3 = eval(x, envir = parent.frame()) > str(r3) > #-------------------------------------------- > > now, the third eval _yields_ a result, although according to > your explanation `x' should be searched for in the global > env. (as was actually the case in my initial example). what > am I missing this time? is `x' copied into the call as a > constant and no longer searched at all or something like > that? > > } > > > > It all makes sense: when you write the function you've got no idea what > > the caller will be like, so you can't refer to its environment in your > > defaults. On the other hand, when you call a function you shouldn't > > care what its internal environment looks like, so your arguments should > > be evaluatable in your own environment, and their value shouldn't change > > just because the implementation of the function changes. > > I presume, one could argue for the opposite behaviour as > well? maybe there is some language out there actually doing > it the other way (passing the unevaluated argument string > and leaving everything to the called function)? I will try > to remember this "detail" and then it's fine with me, but > from the outset it's quite irritating that writing down a > call which is identical to the definition of the function > (including its defaults) does not necessarily yield the same > result as when the defaults are really used. > > > > > This all gets more complicated with formulas in functions like nls(). > > Formulas normally have an environment attached to them too, but > > sometimes people mess with it, and then things can go crazy. > > hope you're not meaning me... > > > thanks > > joerg > > > > > Duncan Murdoch > > > > > >regards, > > > > > >joerg > > > > > >______________________________________________ > > >R-help@r-project.org mailing list > > >https://stat.ethz.ch/mailman/listinfo/r-help > > >PLEASE do read the posting guide > > >http://www.R-project.org/posting-guide.html > > >and provide commented, minimal, self-contained, reproducible code. > > > > ______________________________________________ > R-help@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. > ______________________________________________ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.