**Struggling Through Problems**, and kindly contributed to R-bloggers)

Ross Ikaha (via Xi'an -- thanks ;) ) gives a nice example to show why R is basically impossible to optimize:

> f = function() {

> if (runif(1) > 0.5) {

> x = 10

> }

> x

> }

`x`

in the last expression could be a local or a global,
and this won't be known until runtime!

That's pretty good.

I wonder if this will always return 10:

> f = function() {

> a = 10

> a

> }

> f()

[1] 10

Maybe we could optimize it out? No:

> regular.equals <- `=`

> `=` = function(...) {

> with(parent.frame(), a <- 11)

> }

> f()

[1] 11

> `=` <- regular.equals

OK but assigning to ``=``

is really cheating. This is cheating
too:

> regular.brace = `{`

> `{` = function(...) 11

> f()

[1] 11

> `{` = regular.brace

If ``=``

and ``{``

weren't available for assignment,
is there any way to make `f`

not return 10? Well there's this, but
it's hardly "making f return 10":

> body(f) = quote(11)

> f()

[1] 11

I can't think of any other way to attack it; so if you block all those I guess we can declare this function safe ;)

How about this one:

> g = function(x, y) {

> x + y

> }

Could we safely say that while `g()`

is being called,
`f()`

will never be called at the same time (ie so that we could
overlay their stacks?)

No, not even close. There are a million ways to break that:

> g(f(), f())

[1] 22

(Lazy evaluation -- `f()`

is called while executing
`g()`

)

> normal.plus = `+`

> `+` = function(a, b) UseMethod("+")

> `+.numeric` = function(a, b) { f() * a * b }

> g(1, 2)

[1] 22

> `+` = normal.plus

(Generic ``+``

is not uncommon).

Well at least can we say `g()`

will always evaluate both
arguments? No:

> g(return(2), print("hi"))

[1] 2

Which can make code that looks like an error be valid:

> g(return(2), not.defined)

[1] 2

If you assume g() is strict you will knock out some perfectly legitimate R code :)

Likewise an explicit call to `return()`

doesn't have to actually
do anything:

> g = function(x) {

> 3

> }

> g(return(2))

[1] 3

I also find these hacks delightful:

> delayedAssign('b', {b <- 7; 8})

> a <- b

> a

[1] 8

> b

[1] 7

> x = '@'

> up = function() {

> x. <- x

> x <<- intToUtf8(utf8ToInt(x)+1L)

> delayedAssign(x, up(), ass=.GlobalEnv)

> x.

> }

> up()

[1] "@"

> A

[1] "A"

> B

[1] "B"

> C

[1] "C"

> D

[1] "D"

> backw = function(...) {

> args = as.list(substitute(list(...)))[-1L]

> env = parent.frame()

>

> for (arg in rev(args)) {

> res <- eval(arg, env)

> }

> res

> }

> environment(backw) = baseenv()

> `{` = backw

> fib = function(n) {

> a

> for (i in 1:n) {

> a = b - a

> b = a + b

> }

> b = 1

> a = 1

> }

> fib(8)

[1] 34

> lex.scope = function(...) {

> args = as.list(substitute(list(...)))[-1L]

> parent = parent.frame()

> env = new.env(parent=parent)

>

> for (arg in args) {

> res <- eval(arg, env)

> }

> res

> }

> environment(lex.scope) = baseenv()

> `{` = lex.scope

> {

> x = 2

> {

> x = 3

> }

> x

> }

[1] 2

(Hey, that one could actually be useful).

> evanescent = function(x, v) {

> force(v)

> env = parent.frame()

> name = as.character(substitute(x))

>

> delayedAssign(name, {

> env[[name]] = alist(x=)$x

> v

> }, ass = env

> )

> }

> environment(evanescent) = baseenv()

> `=` = evanescent

> a = 2

> a

[1] 2

> a

Error in eval(expr, envir, enclos) :

argument "a" is missing, with no default

My thoughts on all this: R is a wonderful and flexible language, but it is entirely not the right language for intense numerical calculation: it is simply too flexible to be fast. And unfortunately whenever you're trying some algorithm that hasn't been done before, it will necessarily not already be written in C, and you find yourself having to make a choice: at what point is it too slow to keep in R, and the best thing to do is to give up and rewrite it in C?

The thing is, as an interactive environment, R's flexibility really gains
something (think how you'd implement `with()`

in Python). I personally am OK with the current system of using R for high level
code and ducking to C for tight loops; it's better than trying to make one
language be good at 2 different things.

**leave a comment**for the author, please follow the link and comment on his blog:

**Struggling Through Problems**.

R-bloggers.com offers

**daily e-mail updates**about R news and tutorials on topics such as: visualization (ggplot2, Boxplots, maps, animation), programming (RStudio, Sweave, LaTeX, SQL, Eclipse, git, hadoop, Web Scraping) statistics (regression, PCA, time series, trading) and more...