Jeff Newmiller
2016-Nov-14 02:42 UTC
[R] Question about expression parser for "return" statement
I find your response here inconsistent... either including `return` causes a "wasted" function call to occur (same result achieved slower) or the parser has an optimization in it to prevent the wasted function call (only behaviorally the same). I carefully avoid using the return function in R. Both because using it before the end of a function usually makes the logic harder to follow and because I am under the impression that using it at the end of the function is a small but pointless waste of CPU cycles. That some people might be prone to writing a C-like use of "return;" which causes a function object to be returned only increases my aversion to using it. -- Sent from my phone. Please excuse my brevity. On November 13, 2016 3:47:10 AM PST, Duncan Murdoch <murdoch.duncan at gmail.com> wrote:>On 13/11/2016 12:50 AM, Dave DeBarr wrote: >> I've noticed that if I don't include parentheses around the intended >return >> value for the "return" statement, R will assume the first >parenthetical >> expression is the intended return value ... even if that >parenthetical >> expression is only part of a larger expression. >> >> Is this intentional? > >Yes, return is just a function call that has side effects. As far as >the parser is concerned, > >return ((1/sqrt(2*pi*Variance))*exp(-(1/2)*((x - Mean)^2)/Variance)) > >is basically the same as > >f((1/sqrt(2*pi*Variance))*exp(-(1/2)*((x - Mean)^2)/Variance)) > >Duncan Murdoch > >> >> I'm guessing it is intentional; but since there is no warning about >> ignoring the rest of the expression, it could lead to hard-to-find >bugs. >> >> Thanks, >> Dave >> >> Here's an example ... >> >> dnorm(2, 0, 1) >> normalDensityFunction = function(x, Mean, Variance) { >> # no parentheses surrounding the entire "return" value >> return (1/sqrt(2*pi*Variance))*exp(-(1/2)*((x - >Mean)^2)/Variance) >> } >> normalDensityFunction(2, 0, 1) # incorrect answer >> normalDensityFunction = function(x, Mean, Variance) { >> # parentheses surrounding the entire "return" value >> return ((1/sqrt(2*pi*Variance))*exp(-(1/2)*((x - >Mean)^2)/Variance)) >> } >> normalDensityFunction(2, 0, 1) # correct answer >> >> [[alternative HTML version deleted]] >> >> ______________________________________________ >> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see >> https://stat.ethz.ch/mailman/listinfo/r-help >> PLEASE do read the posting guide >http://www.R-project.org/posting-guide.html >> and provide commented, minimal, self-contained, reproducible code. >> > >______________________________________________ >R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see >https://stat.ethz.ch/mailman/listinfo/r-help >PLEASE do read the posting guide >http://www.R-project.org/posting-guide.html >and provide commented, minimal, self-contained, reproducible code.
Duncan Murdoch
2016-Nov-14 10:12 UTC
[R] Question about expression parser for "return" statement
On 13/11/2016 9:42 PM, Jeff Newmiller wrote:> I find your response here inconsistent... either including `return` causes a "wasted" function call to occur (same result achieved slower) or the parser has an optimization in it to prevent the wasted function call (only behaviorally the same).I don't understand what you are finding inconsistent. I wasn't talking about wasting anything. I was just saying that expressions like return (a)*b are evaluated by calling return(a) first, because return() is a function, and then they'll never get to the multiplication. BTW, there don't appear to be many instances of this particular bug in CRAN packages, though I don't have a reliable test for it yet. The most common error seems to be using just "return", as mentioned before. The fix for that is to add parens, e.g. "return()". The next most common is something like invisible(return(x)) which returns x before making it invisible. The fix for this is to use return(invisible(x))> I carefully avoid using the return function in R. Both because using it before the end of a function usually makes the logic harder to follow and because I am under the impression that using it at the end of the function is a small but pointless waste of CPU cycles. That some people might be prone to writing a C-like use of "return;" which causes a function object to be returned only increases my aversion to using it.Sometimes it is fine to use return(x), but it shouldn't be used routinely. Duncan Murdoch> -- Sent from my phone. Please excuse my brevity. On November 13, 2016 > 3:47:10 AM PST, Duncan Murdoch <murdoch.duncan at gmail.com> wrote: >> >On 13/11/2016 12:50 AM, Dave DeBarr wrote: >>> >> I've noticed that if I don't include parentheses around the intended >> >return >>> >> value for the "return" statement, R will assume the first >> >parenthetical >>> >> expression is the intended return value ... even if that >> >parenthetical >>> >> expression is only part of a larger expression. >>> >> >>> >> Is this intentional? >> > >> >Yes, return is just a function call that has side effects. As far as >> >the parser is concerned, >> > >> >return ((1/sqrt(2*pi*Variance))*exp(-(1/2)*((x - Mean)^2)/Variance)) >> > >> >is basically the same as >> > >> >f((1/sqrt(2*pi*Variance))*exp(-(1/2)*((x - Mean)^2)/Variance)) >> > >> >Duncan Murdoch
Jeff Newmiller
2016-Nov-14 17:57 UTC
[R] Question about expression parser for "return" statement
Sorry, I missed the operation-after-function call aspect of the OP question. However, I think my policy of avoiding the return function as much as possible serves as an effective antibugging strategy for this problem, in addition to its other benefits. -- Sent from my phone. Please excuse my brevity. On November 14, 2016 2:12:49 AM PST, Duncan Murdoch <murdoch.duncan at gmail.com> wrote:>On 13/11/2016 9:42 PM, Jeff Newmiller wrote: >> I find your response here inconsistent... either including `return` >causes a "wasted" function call to occur (same result achieved slower) >or the parser has an optimization in it to prevent the wasted function >call (only behaviorally the same). > >I don't understand what you are finding inconsistent. I wasn't talking > >about wasting anything. I was just saying that expressions like > >return (a)*b > >are evaluated by calling return(a) first, because return() is a >function, and then they'll never get to the multiplication. > >BTW, there don't appear to be many instances of this particular bug in >CRAN packages, though I don't have a reliable test for it yet. The >most >common error seems to be using just "return", as mentioned before. The > >fix for that is to add parens, e.g. "return()". The next most common >is >something like > >invisible(return(x)) > >which returns x before making it invisible. The fix for this is to use > >return(invisible(x)) > > >> I carefully avoid using the return function in R. Both because using >it before the end of a function usually makes the logic harder to >follow and because I am under the impression that using it at the end >of the function is a small but pointless waste of CPU cycles. That some >people might be prone to writing a C-like use of "return;" which causes >a function object to be returned only increases my aversion to using >it. > >Sometimes it is fine to use return(x), but it shouldn't be used >routinely. > >Duncan Murdoch > >> -- Sent from my phone. Please excuse my brevity. On November 13, 2016 >> 3:47:10 AM PST, Duncan Murdoch <murdoch.duncan at gmail.com> wrote: >>> >On 13/11/2016 12:50 AM, Dave DeBarr wrote: >>>> >> I've noticed that if I don't include parentheses around the >intended >>> >return >>>> >> value for the "return" statement, R will assume the first >>> >parenthetical >>>> >> expression is the intended return value ... even if that >>> >parenthetical >>>> >> expression is only part of a larger expression. >>>> >> >>>> >> Is this intentional? >>> > >>> >Yes, return is just a function call that has side effects. As far >as >>> >the parser is concerned, >>> > >>> >return ((1/sqrt(2*pi*Variance))*exp(-(1/2)*((x - >Mean)^2)/Variance)) >>> > >>> >is basically the same as >>> > >>> >f((1/sqrt(2*pi*Variance))*exp(-(1/2)*((x - Mean)^2)/Variance)) >>> > >>> >Duncan Murdoch