Here is a small chunk of R from Luke Tierney's codetools package:
if (! exists("callCC"))
callCC <- function(fun) {
value <- NULL
delayedAssign("throw", return(value))
fun(function(v) { value <<- v; throw })
}
Can someone explain this to me? In particular, why the shenanigans with throw
rather than just writing return(value)
?
The original is here: https://gitlab.com/luke-tierney/codetools/-/blob/master/R/codetools.R
CodePudding user response:
Have you read the help page?
callCC provides a non-local exit mechanism that can be useful for early termination of a computation. callCC calls fun with one argument, an exit function. The exit function takes a single argument, the intended return value. If the body of fun calls the exit function then the call to callCC immediately returns, with the value supplied to the exit function as the value returned by callCC.
The reason not to call return(value)
is that it would return from the wrong place, or return the wrong value. If the code was
callCC <- function(fun) {
value <- NULL
return(value)
fun(function(v) { value <<- v; throw })
}
it would always return NULL
. If it was
callCC <- function(fun) {
value <- NULL
fun(function(v) { value <<- v; return(value) })
}
it would return from the anonymous function, and continue within fun
. What the real callCC
does is exit all the way out of callCC
.