Question about expression parser for "return" statement

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Question about expression parser for "return" statement

Dave DeBarr-2
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?

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]]

______________________________________________
[hidden email] 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.
Reply | Threaded
Open this post in threaded view
|

Re: Question about expression parser for "return" statement

Duncan Murdoch-2
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]]
>
> ______________________________________________
> [hidden email] 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.
>

______________________________________________
[hidden email] 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.
Reply | Threaded
Open this post in threaded view
|

Re: Question about expression parser for "return" statement

Duncan Murdoch-2
On 13/11/2016 6:47 AM, Duncan Murdoch 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))

By the way, out of curiosity I took a look at the source of CRAN
packages to see if this actually occurs.  It turns out that "return" is
used as a variable name often enough to make automatic tests tricky, so
I don't know the answer to my question.  However, I did turn up a number
of cases where people have code like this:

     if (name == "") return;

(from the bio.infer package), which never calls return(), so doesn't
actually do what the author likely intended.

Duncan Murdoch

>
> 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]]
>>
>> ______________________________________________
>> [hidden email] 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.
>>
>

______________________________________________
[hidden email] 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.
Reply | Threaded
Open this post in threaded view
|

Re: Question about expression parser for "return" statement

Duncan Murdoch-2
On 13/11/2016 7:58 AM, Duncan Murdoch wrote:

> On 13/11/2016 6:47 AM, Duncan Murdoch 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))
>
> By the way, out of curiosity I took a look at the source of CRAN
> packages to see if this actually occurs.  It turns out that "return" is
> used as a variable name often enough to make automatic tests tricky, so
> I don't know the answer to my question.  However, I did turn up a number
> of cases where people have code like this:
>
>      if (name == "") return;
>
> (from the bio.infer package), which never calls return(), so doesn't
> actually do what the author likely intended

I searched the R sources and the sources of CRAN packages, and found
this is a reasonably common problem:  it's in 111 packages, including
one in base R.  I'll be emailing the maintainers to let them know.

I'll see about putting a check for this into R CMD check.

Duncan Murdoch

______________________________________________
[hidden email] 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.
Reply | Threaded
Open this post in threaded view
|

Re: Question about expression parser for "return" statement

Jeff Newmiller
In reply to this post by Duncan Murdoch-2
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 <[hidden email]> 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]]
>>
>> ______________________________________________
>> [hidden email] 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.
>>
>
>______________________________________________
>[hidden email] 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.

______________________________________________
[hidden email] 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.
Reply | Threaded
Open this post in threaded view
|

Re: Question about expression parser for "return" statement

Duncan Murdoch-2
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 <[hidden email]> 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

______________________________________________
[hidden email] 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.
Reply | Threaded
Open this post in threaded view
|

Re: Question about expression parser for "return" statement

Wolf, Steven
In reply to this post by Duncan Murdoch-2
Just to add on a bit, please note that the return is superfluous.  If you write this:


normalDensityFunction = function(x, Mean, Variance) {

    # no  "return" value given at all

    (1/sqrt(2*pi*Variance))*exp(-(1/2)*((x - Mean)^2)/Variance)

}

normalDensityFunction(2,0,1)

...you get the right answer again.

This is not "best practices", and Duncan will probably give you 10 reasons why you should never do it this way.  But if the parentheses behavior bothers you enough, you can subvert it.  This probably won't work so well if you try to make any more complicated output.

Caveat Emptor.

-SW


--
Steven Wolf, PhD
Assistant Professor
Department of Physics
STEM CoRE -- STEM Collaborative for Research in Education
http://www.ecu.edu/cs-acad/aa/StemCore
East Carolina University
Phone: 252-737-5229




On Sun, 2016-11-13 at 13:35 -0500, Duncan Murdoch wrote:

On 13/11/2016 7:58 AM, Duncan Murdoch wrote:


On 13/11/2016 6:47 AM, Duncan Murdoch 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))



By the way, out of curiosity I took a look at the source of CRAN
packages to see if this actually occurs.  It turns out that "return" is
used as a variable name often enough to make automatic tests tricky, so
I don't know the answer to my question.  However, I did turn up a number
of cases where people have code like this:

     if (name == "") return;

(from the bio.infer package), which never calls return(), so doesn't
actually do what the author likely intended



I searched the R sources and the sources of CRAN packages, and found
this is a reasonably common problem:  it's in 111 packages, including
one in base R.  I'll be emailing the maintainers to let them know.

I'll see about putting a check for this into R CMD check.

Duncan Murdoch




        [[alternative HTML version deleted]]

______________________________________________
[hidden email] 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.
Reply | Threaded
Open this post in threaded view
|

Re: Question about expression parser for "return" statement

Duncan Murdoch-2
On 14/11/2016 11:26 AM, Wolf, Steven wrote:

> Just to add on a bit, please note that the return is superfluous.  If
> you write this:
>
> normalDensityFunction = function(x, Mean, Variance) {
>      # no  "return" value given at all
>      (1/sqrt(2*pi*Variance))*exp(-(1/2)*((x - Mean)^2)/Variance)
> }
> normalDensityFunction(2,0,1)
>
> ...you get the right answer again.
>
> This is not "best practices", and Duncan will probably give you 10
> reasons why you should never do it this way.  But if the parentheses
> behavior bothers you enough, you can subvert it.  This probably won't
> work so well if you try to make any more complicated output.

Why do you say that's not best practice?  I would say that's preferable
to an explicit return().

Duncan

>
> Caveat Emptor.
>
> -SW
>
> --
> Steven Wolf, PhD
> Assistant Professor
> Department of Physics
> STEM CoRE -- STEM Collaborative for Research in Education
> http://www.ecu.edu/cs-acad/aa/StemCore
> East Carolina University
> Phone: 252-737-5229
>
>
>
> On Sun, 2016-11-13 at 13:35 -0500, Duncan Murdoch wrote:
>> On 13/11/2016 7:58 AM, Duncan Murdoch wrote:
>>> On 13/11/2016 6:47 AM, Duncan Murdoch 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))
>>> By the way, out of curiosity I took a look at the source of CRAN
>>> packages to see if this actually occurs. It turns out that "return"
>>> is used as a variable name often enough to make automatic tests
>>> tricky, so I don't know the answer to my question. However, I did
>>> turn up a number of cases where people have code like this: if (name
>>> == "") return; (from the bio.infer package), which never calls
>>> return(), so doesn't actually do what the author likely intended
>>
>>
>> I searched the R sources and the sources of CRAN packages, and found
>> this is a reasonably common problem:  it's in 111 packages, including
>> one in base R.  I'll be emailing the maintainers to let them know.
>>
>> I'll see about putting a check for this into R CMD check.
>>
>> Duncan Murdoch
>>
>>

______________________________________________
[hidden email] 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.
Reply | Threaded
Open this post in threaded view
|

Re: Question about expression parser for "return" statement

wolfste4
I stand corrected.  I have been chided in the past for not explicitly returning my output by someone claiming it is not best practices.

-Steve

On Mon, 2016-11-14 at 12:22 -0500, Duncan Murdoch wrote:

On 14/11/2016 11:26 AM, Wolf, Steven wrote:


Just to add on a bit, please note that the return is superfluous.  If
you write this:

normalDensityFunction = function(x, Mean, Variance) {
     # no  "return" value given at all
     (1/sqrt(2*pi*Variance))*exp(-(1/2)*((x - Mean)^2)/Variance)
}
normalDensityFunction(2,0,1)

...you get the right answer again.

This is not "best practices", and Duncan will probably give you 10
reasons why you should never do it this way.  But if the parentheses
behavior bothers you enough, you can subvert it.  This probably won't
work so well if you try to make any more complicated output.



Why do you say that's not best practice?  I would say that's preferable
to an explicit return().

Duncan



Caveat Emptor.

-SW



        [[alternative HTML version deleted]]

______________________________________________
[hidden email] 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.
Reply | Threaded
Open this post in threaded view
|

Re: Question about expression parser for "return" statement

Jeff Newmiller
In reply to this post by Duncan Murdoch-2
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 <[hidden email]> 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 <[hidden email]> 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

______________________________________________
[hidden email] 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.