At the outset, I think we need to clarify the scope of the question.
- If you write a function in R, it is good practice to return value using either
return()
at the end of the function, for clarity, or at least putting the data object last before the curly brackets. in this context, the use of <<-
can create any sort of errors and complications (in short is a reminder of spaghetti programming, breaking the rule of having a single exit point to the function in question).
- Different is the case of
shiny
special functions. I just like to remind that shiny
coders usually does not use return()
at the end of a shiny function (even if it would still work). Here either there is no value returned, or reactive
is used or other similar constructs.
Part of the confusion comes from the minimal example in the question: the example is not a shiny
special function but just a normal function.
In shiny
, using for example constructs like observe
, it may happen to use <<-
to update global objects. A very good example (a great piece of code I often go back to) is the application ShinyChat developed by Jeff Allen, one of shiny developers - see here on github.
In this case Jeff uses <<-
to update a reactiveValue defined at the global level from within an observe
function: very good style.
I conclude with a minor point: if you have any function and you update a variable with <<-
, and you have a variable of the same name defined locally, only the global variable is updated.
In these cases you need to do something like
data <<- data <- 3
From right to left: the first <-
updated the local variable named data
: the second <<-
updated the global variable named data
. Talk about confusing.
On the other hand, in shiny or standard R I never noticed a drastic slowness because of <<-
, certainly provided that there aren't too many in the code.
On the issue of alternative techniques like reactive
or reactiveValues
, please see this good answer on SO to a similar question here.