On 23/12/2007 9:15 AM, Duncan Murdoch wrote: > On 22/12/2007 5:45 PM, Charilaos Skiadas wrote: >> On Dec 22, 2007, at 4:44 PM, Duncan Murdoch wrote: >>>> 5) eval then creates the environment where this evaluation will >>>> take place. It does that by creating an environment containing >>>> the frame "a=5", and with enclosing environment the parent frame >>>> of foo, which is bar's environment. >>>> 6) So, as I understand it, the symbol "er" is going to now be >>>> evaluated in an environment where a is set to 5 and er is set to >>>> a, along with whatever is in the user's workspace. >>> I think this part is wrong. A better description is: >>> >>> er is going to be evaluated in an environment where a is set to 5. >>> The parent of that environment is the bar evaluation frame, where >>> er is set to be a promise to evaluate a in the global environment. >>> >>>> 7) So the first step now is looking up a definition for er. >>>> Nothing is found in the current frame, so the evaluation proceeds >>>> to bar's environment, where the association "er=a" is found, so >>>> er is replaced by a. >>> No, at this point an attempt is made to force the promise. >>> Promises have their own associated environments, and that's where >>> the evaluation takes place. In the case of the er object, the >>> associated environment is the one where bar(a) was called, i.e. the >>> global environment. >>> >>>> 8) Now, and perhaps this is where I misunderstand things, the >>>> lookup for a will take place. My thinking was that the lookup >>>> would start from the evaluation environment that eval created, >>>> and hence would locate the a=5 value. But this is clearly not >>>> what happens. >>>> Anyway, hope someone will correct me where I'm wrong, and explain >>>> to me what I am doing wrong, and ideally how to diagnose such >>>> things. >>> Diagnosing things like this is hard. Promises are very difficult >>> things to look at: as soon as you try to do anything with them >>> they get evaluated, and there's no way in R code to display them >>> without that. >>> You can use substitute() to extract the expression part, but >>> there's no way to extract the environment part. Maybe there should >>> be, but it's tricky to get the semantics right. If the function >>> environment() worked to extract the environment of a promise, then >>> all sorts of code would fail where I really wanted to evaluate the >>> arg before extracting the environment. >> Thank you Duncan, for the very clear explanation. >> >> Ok, so the substitute "breaks through" the promise of expr, returning >> as a language object the promise of er, and there's no easy way to >> break through that. I ended up with the following, somewhat uglier >> than I wanted, code, which seems to do what I need in this case, and >> hopefully will still work in the more general case I want it to. The >> idea was to break through the er promise in bar, before sending it >> over to foo. Then foo receives simply an expression, which it can >> then evaluate. Though I seem to have had to work a bit harder on that >> part than I expected to. Perhaps there's an easier way? Or things >> that can go seriously wrong with this way? >> >> foo <- function(fr, expr) { >> ..obj <- list(.=fr) >> ..expr <- substitute(expr) >> ..txt <- parse( text=paste("substitute(",..expr,")") ) > > I think you want > > ..txt <- parse( text=paste("substitute(",deparse(..expr),")") ) > > here, but it's even better not to go through the deparse-parse cycle: > > ..txt <- bquote( substitute( .(..expr) ) ) > > The main thing that could go wrong ...
Sorry, this wasn't written clearly: This was a response to your second question, not a continuation of the bquote() suggestion. Duncan Murdoch is the evaluation of er might not be > right. Just because it is an argument to bar doesn't mean bar's frame > or parent.frame() is the right place to evaluate it. > > To check for errors, I'd introduce like-named variables at lots of > levels, and then put them into the expression you were evaluating in > such a way that you can tell which one was found. For example, put > x <- "foo" into foo(), x <- "bar" into bar(), and x <- "global" into the > global environment. Then evaluate some expression that prints x and > make sure you see the right one. > > Duncan Murdoch > >> ..expr <- eval(..txt, ..obj, parent.frame()) >> ..expr <- eval(..expr, parent.frame()) >> eval(..expr, ..obj) >> } >> bar <- function(parent, er, ...) { >> .fr=parent >> g <- substitute(er) >> foo(.fr, g) >> } >> >> > foo(5,.) >> [1] 5 >> > bar(5,.) >> [1] 5 >> >> >>> Duncan Murdoch >> Haris Skiadas >> Department of Mathematics and Computer Science >> Hanover College >> >> ______________________________________________ >> 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.