Martin
Martin

Reputation: 594

Variable declaration / "option explicit" in R

R is fantastic: lean and flexible, but powerful and open. For small tasks it is convenient if one does not have to declare each variable before use. BUT: esp. in larger projects, small typos can mess up everything, possibly even without an eror message (see example)!

Is there a workaround? If not within plain R, possibly also by an editor that asks for a declaration block? Something like "option explicit" in VBA? I am aware of the very nice highlighting of same variables in the RStudio editor when marking it, but if variables in question are far apart this becomes less useful.

Just for clarity: I am not looking for a more elegant/less error-prone implementation of this function, which was created merely to provide a demo.

# without typo
fun <- function(x) {
  a <- x
  if (a<0) {
    if (a > -50) x <- -1 else x <- -2
  }
  return(x)
}

# even if masters will spot the typo on the first glance...
fun.typo <- function(x) {
  a <- x
  if (a<0) {
    if (a > -50) x <- -1 else X <- -2
  }
  return(x)
}

fun( 50) # 50
fun(-40) # -1
fun(-60) # -2

fun.typo( 50) #  50
fun.typo(-40) #  -1
fun.typo(-60) # -60 (*** unintended, should be -2 ***)

Upvotes: 3

Views: 864

Answers (1)

Vincent Guillemot
Vincent Guillemot

Reputation: 3429

A very "dirty" solution would be to systematically check that the function's local environment is not changed after the "preamble".

fun <- function(x) {
  a <- x
  ls1 <- ls()
  if (a<0) {
    if (a > -50) x <- -1 else x <- -2
  }
  ls2 <- ls()
  print(list(c(ls1,"ls1"),ls2))
  if (!setequal(c(ls1,"ls1"), ls2)) stop("Something went terribly wrong!")
  return(x)
}

fun.typo <- function(x) {
  a <- x
  ls1 <- ls()
  if (a<0) {
    if (a > -50) x <- -1 else X <- -2
  }
  ls2 <- ls()
  print(list(c(ls1,"ls1"),ls2))
  if (!setequal(c(ls1,"ls1"), ls2)) stop("Something went terribly wrong!")
  return(x)
}

With this "solution", fun.typo(-60) no longer silently gives a wrong answer...

Upvotes: 2

Related Questions