Friday, February 27, 2009

R Language - once more

An early warning for the unwary hacker.

Normal-order evaluation

Y <- function (f)
  (function (x) f(x(x))) (function (x) f(x(x)))

FAC <- function (f) function(n)
  (if (n == 0) 1 else n * f(n - 1))

> Y(fac)(10)
[1] 3628000

Quoting and macros

fn <- function(x) {
   x <- substitute(x);
   f <- list(NULL, x[[2]]);
   names(f) <- c(x[[3]], "");
   as.function(f, envir=parent.frame());
}

y   <- fn(f -> fn(x -> f(x(x)))(fn(x -> f(x(x)))))
fac <- fn(f -> fn(n -> if (n == 0) 1 else n * f(n - 1)))
> y(fac)(10)
[1] 3628800

Coercions

> NULL == FALSE
logical(0)

If you are wondering what happened here, FALSE, which is a logical vector of length 1, was compared for equality with NULL, which is an empty list. To proceed with the comparison, R coerced the list to a vector of length 0. Then, two logical vectors were compared elementwise for equality, to yield the resulting vector of length 0.

Equational reasoning is not a good starting point to make sense of this:

> NULL == NULL
logical(0)

> logical(0) == FALSE
logical(0)

Side effects

> f <- function () { print("MISSILES LAUNCHED"); 1 }
> g <- function (x <- f()) { x + 1 }
> g()
[1] "MISSILES LAUNCHED"
[1] 2
> g(1)
[1] 2

Argument parsing

> f <- function (x = y + 1, y = x + 1) { y <- 2; y }
> f()
[1] 2

Summary

Can a language safely combine the above features?

Does statistics really nead such a language?

References

No comments:

Post a Comment