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.