Hacker News new | ask | show | jobs
by civilized 744 days ago
R is not lazy. It has non-standard evaluation mechanisms (formulas, promises, quosures...) that enable to you to write domain-specific languages that "do what the user meant".

If your code (or the code of the libraries you're using) doesn't use any non-standard evaluation tools, evaluation will be eager and work like any other ALGOL language.

It is possible to make some objects behave in a lazy way, but this is also true of many other languages.

4 comments

R is lazy, because it does not evaluate arguments upon function call unless and until used. It is also unusual in that the function can avoid evaluating the argument at all, and instead ask for the quoted expression that produced it (which can then be evaluated manually at the desired point, or multiple times, or in a different environment etc), but that is orthogonal to laziness.

To be even more precisely, R itself is lazy "all the way through". Because literally every expression in R is syntactic sugar for a function call (including assignments and control structures such as "if"), the only thing that a function can really do with an argument is pass it on to another function, so, strictly speaking, there's no distinction between use and non-use even. It's just that any R function, in order to do something useful, will ultimately call some non-R leaf function implemented in native code, and some of those leaf functions will actually do the eval if they're defined in terms of argument values (e.g. obviously addition needs to do so to actually compute the value etc).

R's evaluation of arguments is lazy, so while not at the level of Haskell it feels like a lazy language to me. Try eg:

  f = function(x) { print('hello'); x }
  f(print('world'))
X is not evaluated in f until referenced. Indeed if you remove x from f, world is not printed.
Apologies, my bad, but I'm a bit too late to edit. The experts say that R qualifies as a lazy language [1, 2].

My impression was that R was mostly an eager language that somehow allowed for laziness. I will research this further and hopefully suss out why I got confused.

[1] https://dl.acm.org/doi/10.1145/3360579

[2] https://www.r-bloggers.com/2018/07/about-lazy-evaluation/

Thank you for the correction. Is it possible to use NSE in say Python or JavaScript?
Yes, though the languages do not support it explicitly you can simulate lazy evaluation by wrapping all your arguments in closures. This way they won't be evaluated until called within the function body.
Sidenote, the evaluation model of python can be surprising. List comprehension will create implicit function scopes that can trip you up.