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. 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. 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. 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.