Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why expression after return's parenthesis is checked for lexical correctness, but is not evaluated?

Tags:

r

Consider the following code:

a = function() {
  return (23)
}
b = function() {
  return (23) * 23
}
c = function() {
  return (23) * someUndefinedVariable
}

All of the above runs successfully (if called) and return 23. I assumed that R ignores everything that goes after the closing parenthesis of return, but it does not really, because this code fails during code loading:

d = function() {
  return (23) something
}

My assumption is that in the latter example some lexer or parser fails. But in the former, expression is parsed as (return(23))*some (because return is treated like a function), but evaluation stops at return and therefore R does not try to find some.

Does that sounds ok? Is that the reason? Is such behavior intended? Can I enable some warnings so that interpreter tells me about such 'unreachable code'?

like image 691
yeputons Avatar asked Mar 12 '15 19:03

yeputons


3 Answers

The failure of this code:

d = function() {
  return (23) something
}

... has nothing to do with the prior code and everything to do with the inability to parse: return (23) something. Unlike the earlier misguided attempt to redefine c which had a valid/parseable function body, the d-body is incapable of being put into a functional form. The parser doesn't really stop at return(23) but rather after it tokenizes something and "realizes" that it is not a semicolon or an infix function name. So the R interpreter now has two expressions and no valid connector/separator between them.

The referenced objects inside R function bodies at the time of definition do not get evaluated or even checked for existence in the parameter list or outside the function. (R is not a compiler.)

like image 169
IRTFM Avatar answered Oct 19 '22 12:10

IRTFM


R parses the statement before it is evaluated:

parse(text = "funky <- function(x) {
        return(x) * dog
}")

returns:

expression(funky <- function(x) {
        return(x) * dog
})

However,

parse(text = "funky <- function(x) {
         return(x) dog
}")

returns:

Error in parse(text = "funky <- function(x) {\n        return(x) dog\n}") : 
  <text>:2:19: unexpected symbol
1: funky <- function(x) {
2:         return(x) dog
                     ^

In the above example, even though the variable dog doesn't exist (and comes after return), R is still able to parse it as it correct code.

like image 3
Richard Border Avatar answered Oct 19 '22 10:10

Richard Border


return is not just "treated like a function", it is a function. And anytime it's called, the code path will exit from whatever function you're in at that moment.

So that means that by the time R would have gotten to multiplying the result of return by 23, it's all over, that evaluation stops, and there are no errors or warnings to report (just like there are no warnings or errors when you return inside some if condition).

Whereas your last function simply cannot be parsed (which more or less means that the expression is put into a function tree), and so that (function) object can't be created.

like image 3
eddi Avatar answered Oct 19 '22 10:10

eddi