Well a somewhat unique feature or R is automatic argument recycling, so that when doing operations on dataframes, it's a lot easier to incorporate data from outside of the dataframe into evaluation. Let's say you are doing a stepwise logisitic growth model, like dP/dt = r*P*(1 - P/K). Let's say that r a known single value in the global environment, K is going be predicted from some environmental variables within your dataframe, and P is going to be given as an initial condition and its evolution modeled. The R way of looking at this would be to set up an environment where the dataframe environment inherits from the global environment, and to evaluate within this environment regardless of calling environment. That means that within a sub sub function, you can use r to represent, maybe, a row number, and K, to represent, maybe, a column number, and that you can still evaluate an expression like r*P*(1 - P/K) with no problem. This is most useful when writing your own functions. For example, you could build some sort of time-series predictive package that could handle not only logisitic models, but other models, like the Lotka-Volterra models. Now, I'm not saying this is impossible to do in Julia: in fact, I'm quite sure it is. It's just less convenient.
The other nice things about environments are more trivial. For example, you might be doing a homework assignment with several problems. At the start of each problem, you could define a new environment. At the end of the problem, you could display the entire content of the problem's environment as a way to track down errors. When looking at an answer sheet, you could compare intermediate results and see where you went wrong. Again, not impossible to do with Julia; you would probably want to set up a dict for each problem, and do all operations within that dict. Which, I guess, is basically what is happening under the hood in a language with environments. I'll just nod in agreement with the fexpr stuff and pretend I understand. On Friday, July 24, 2015 at 4:11:37 PM UTC-4, Scott Jones wrote: > > I should give you a hard time about arguing from authority ;-), but I was > there at the same time and knew KMP, so I wouldn't want to argue too much > with him either, and I am in agreement with you about fexprs vs. macros, > and the equivalent issues in Julia. > > On Friday, July 24, 2015 at 2:31:54 PM UTC-4, Stefan Karpinski wrote: >> >> Lisp has already been down this path – fexprs >> <https://en.wikipedia.org/wiki/Fexpr> were special forms with behavior >> similar to R's functions, and they were deprecated in the 1980s in favor of >> macros, >> https://en.wikipedia.org/wiki/Fexpr#Mainstream_use_and_deprecation: >> >> His central objection was that, in a Lisp dialect that allows fexprs, >>> static analysis cannot determine generally whether an operator represents >>> an ordinary function or a fexpr — therefore, static analysis cannot >>> determine whether or not the operands will be evaluated. In particular, the >>> compiler cannot tell whether a subexpression can be safely optimized, since >>> the subexpression might be treated as unevaluated data at run-time. >> >> >> If Lispers think a feature is too dynamic and hard to understand, that's >> a danger sign. In general, I wouldn't want to argue too much with Kent >> Pitman :-) >> >> On the subject of Kent Pitman, here's a random bit of Lisp wisdom from this >> interview >> <http://developers.slashdot.org/story/01/11/03/1726251/kent-m-pitman-answers-on-lisp-and-much-more> >> >> with him: >> >> I like Lisp's willingness to represent itself. People often explain this >>> as its ability to represent itself, but I think that's wrong. Most >>> languages are capable of representing themselves, but they simply don't >>> have the will to. Lisp programs are represented by lists and programmers >>> are aware of that. It wouldn't matter if it had been arrays. It does matter >>> that it's program structure that is represented, and not character syntax, >>> but beyond that the choice is pretty arbitrary. It's not important that the >>> representation be the Right® choice. It's just important that it be a >>> common, agreed-upon choice so that there can be a rich community of >>> program-manipulating programs that "do trade" in this common representation. >> >> >> This is probably the best quote about homoiconicity I've read anywhere >> and explains why the term is tricky to pin down. >> >> On Fri, Jul 24, 2015 at 2:21 PM, Brandon Taylor <brandon....@gmail.com> >> wrote: >> >>> Macros seem to have a bunch of limitations. They can't be overloaded to >>> take advantage of Julia's typing system. Their functionality can somewhat >>> mimic evaluation within a function in its direct parent environment, but >>> what if you want to write functions within your macro, or macros inside >>> your macro, etc? Probably still possible to do many things, but it would >>> invovle passing expressions back in forth in confusing ways, where as with >>> environments, as long as an environment is kept attached to every >>> expression, they can be immediately evaluated in any sub or subsub etc. >>> environment. >>> >> >>