On Mon, May 9, 2016 at 7:12 AM, peter dalgaard <pda...@gmail.com> wrote: > > On 09 May 2016, at 02:46 , Bert Gunter <bgunter.4...@gmail.com> wrote: > >> ... To be clear, Hadley or anyone else should also feel free to set me >> straight, preferably publicly, but privately if you prefer. > > Not really to "set anyone straight", but there are some subtleties with mode > call objects versus expression objects and formulas to be aware of. > > E.g., > >> a <- 2 >> do.call("print", list(a*pi)) > [1] 6.283185 >> do.call("print", list(quote(a*pi))) > [1] 6.283185 >> do.call("print", list(expression(a*pi))) > expression(a * pi) >> do.call("print", list(~a*pi)) > ~a * pi > > Thing is, if you insert a call object into a parse tree, nothing is there to > preserve its nature as an unevaluated expression. Similarly, in > >> call("print", quote(a*pi)) > print(a * pi) > > the result is identical to quote(print(a * pi)), so when evaluated, quoting > is not seen by print(). > > As far as I understand, this is also the reason that for math in ggplot, you > may need as.expression(bquote(....)). > > In general, I think that a number of things in R had been more cleanly > implemented using formulas/expression objects than using substitution and > lazy evaluation, notably subset and offset arguments in lm/glm. It would have > been so much cleaner to have > > lm(math ~ age, data = foo, subset = ~ sex=="1") > > than the current situation where lm internally chops its own head off and > substitutes with model.frame, then evaluates the call to model.frame() which > in turn does eval(substitute(subset), data, env). Of course, at the time, ~ > was intended specifically for Wilkinson Rogers type formulas; "abusing" it > for other kinds of expressions is something of an afterthought.
Yeah, to my mind, the cool thing about formulas is that they provide a concise way to capture an environment and an expression, and then Wilkinson Rogers are just a special case. It's obvious impossible to go back and change how lm() etc works now, but I'm reasonably confident that lazyeval provides a strong foundation going forward. The quasiquotation stuff is particularly important - and unquote-splice makes it possible to do things that are impossible with bquote(). (Of course, unquote-splice could be added to bquote(), but I think you'll still run into issues with environments) Hadley -- http://hadley.nz ______________________________________________ R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see 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.