Hacker News new | ask | show | jobs
by jacobolus 5207 days ago
Aside: One of the things that I really don’t like about R coming from a background in other programming languages is that a function is evaluated before its arguments; i.e. an expression passed as a parameter to a function is not a value but is an implicit lambda, to be evaluated multiple times somewhere inside the function.

For example:

  replicate(2, rnorm(2))
creates a 2x2 matrix of independent random values. Whereas:

  x <- rnorm(2)
  replicate(2, x)
Instead creates a 2x2 matrix with a single random value for each row, repeated across all columns. And so if you want to decompose it, you need to do:

  x <- function() rnorm(2)
  replicate(2, x())
Which will re-call x twice inside the replicate function.
1 comments

R does have call-by-need semantics, like (an impure) Haskell, but that's not why replicate's second argument gets evaluated multiple times:

  replicate <- function (n, expr, simplify = TRUE) 
     sapply(integer(n), 
        eval.parent(
           substitute(function(...) expr)), 
      simplify = simplify)
The replicate function uses R's compute-on-the-language to construct a new function that has expr as its body.

A closure's argument will be evaluated at most once.