There's a StackOverflow question
https://stackoverflow.com/q/22024082/2554330 that references this text
from ?missing:
"Currently missing can only be used in the immediate body of the
function that defines the argument, not in the body of a nested function
or a local call. This may change in the future."
Someone pointed out (in https://stackoverflow.com/a/58169498/2554330)
that this isn't true in the examples they've tried: missingness does
get passed along. This example shows it (this is slightly different
than the SO example):
f1 <- function(x, y, z){
if(missing(x))
cat("f1: x is missing\n")
if(missing(y))
cat("f1: y is missing\n")
}
f2 <- function(x, y, z){
if(missing(z))
cat("f2: z is missing\n")
f1(x, y)
}
f2()
which produces
f2: z is missing
f1: x is missing
f1: y is missing
Is the documentation out of date? That quote appears to have been
written in 2002.
Duncan Murdoch
There is "missing with default" and "missing without
default".
If an argument x is missing without a default, then missing(x) is true, if
you pass x to another function, it will pass the value of the "missing
argument". (which is different than simply being missing!)
If an argument x is missing _with_a default, then missing(x) is still true,
but if you pass x to another function, the default value is passed, not the
missing argument symbol.
If you add default arguments to your example, you'll see this effect:
f1 <- function(x, y, z){
if(missing(x))
cat("f1: x is missing\n")
if(missing(y))
cat("f1: y is missing\n")
}
f2 <- function(x, y, z){
if(missing(z))
cat("f2: z is missing\n")
f1(x, y)
}
f2()
prints
f2: z is missing
The intersection of default values, and the representation of missing
without a default as a symbol yields some unexpected and complex behaviors.
Here are a few more fun examples:
https://github.com/bedatadriven/renjin/blob/master/tests/src/test/R/test.missing.R
Best,
Alex
On Tue, Oct 1, 2019, 10:27 Duncan Murdoch <murdoch.duncan at gmail.com>
wrote:
>
> There's a StackOverflow question
> https://stackoverflow.com/q/22024082/2554330 that references this text
> from ?missing:
>
> "Currently missing can only be used in the immediate body of the
> function that defines the argument, not in the body of a nested function
> or a local call. This may change in the future."
>
> Someone pointed out (in https://stackoverflow.com/a/58169498/2554330)
> that this isn't true in the examples they've tried: missingness
does
> get passed along. This example shows it (this is slightly different
> than the SO example):
>
> f1 <- function(x, y, z){
> if(missing(x))
> cat("f1: x is missing\n")
> if(missing(y))
> cat("f1: y is missing\n")
> }
>
> f2 <- function(x, y, z){
> if(missing(z))
> cat("f2: z is missing\n")
> f1(x, y)
> }
>
> f2()
>
> which produces
>
> f2: z is missing
> f1: x is missing
> f1: y is missing
>
> Is the documentation out of date? That quote appears to have been
> written in 2002.
>
> Duncan Murdoch
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>
[[alternative HTML version deleted]]
The updated example was meant to read:
f1 <- function(x = NULL, y = NULL, z = NULL){
if(missing(x))
cat("f1: x is missing\n")
if(missing(y))
cat("f1: y is missing\n")
}
f2 <- function(x = NULL, y = NULL, z = NULL){
if(missing(z))
cat("f2: z is missing\n")
f1(x, y)
}
f2()
Alex
On Tue, Oct 1, 2019 at 10:37 AM Bertram, Alexander <alex at
bedatadriven.com>
wrote:
> There is "missing with default" and "missing without
default".
>
> If an argument x is missing without a default, then missing(x) is true, if
> you pass x to another function, it will pass the value of the "missing
> argument". (which is different than simply being missing!)
>
> If an argument x is missing _with_a default, then missing(x) is still
> true, but if you pass x to another function, the default value is passed,
> not the missing argument symbol.
>
> If you add default arguments to your example, you'll see this effect:
>
> f1 <- function(x, y, z){
> if(missing(x))
> cat("f1: x is missing\n")
> if(missing(y))
> cat("f1: y is missing\n")
> }
>
> f2 <- function(x, y, z){
> if(missing(z))
> cat("f2: z is missing\n")
> f1(x, y)
> }
>
> f2()
>
> prints
>
> f2: z is missing
>
> The intersection of default values, and the representation of missing
> without a default as a symbol yields some unexpected and complex behaviors.
> Here are a few more fun examples:
>
>
https://github.com/bedatadriven/renjin/blob/master/tests/src/test/R/test.missing.R
>
> Best,
> Alex
>
>
>
> On Tue, Oct 1, 2019, 10:27 Duncan Murdoch <murdoch.duncan at
gmail.com>
> wrote:
>
>>
>> There's a StackOverflow question
>> https://stackoverflow.com/q/22024082/2554330 that references this text
>> from ?missing:
>>
>> "Currently missing can only be used in the immediate body of the
>> function that defines the argument, not in the body of a nested
function
>> or a local call. This may change in the future."
>>
>> Someone pointed out (in https://stackoverflow.com/a/58169498/2554330)
>> that this isn't true in the examples they've tried:
missingness does
>> get passed along. This example shows it (this is slightly different
>> than the SO example):
>>
>> f1 <- function(x, y, z){
>> if(missing(x))
>> cat("f1: x is missing\n")
>> if(missing(y))
>> cat("f1: y is missing\n")
>> }
>>
>> f2 <- function(x, y, z){
>> if(missing(z))
>> cat("f2: z is missing\n")
>> f1(x, y)
>> }
>>
>> f2()
>>
>> which produces
>>
>> f2: z is missing
>> f1: x is missing
>> f1: y is missing
>>
>> Is the documentation out of date? That quote appears to have been
>> written in 2002.
>>
>> Duncan Murdoch
>>
>> ______________________________________________
>> R-devel at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>
--
Alexander Bertram
Technical Director
*BeDataDriven BV*
Web: http://bedatadriven.com
Email: alex at bedatadriven.com
Tel. Nederlands: +31(0)647205388
Skype: akbertram
[[alternative HTML version deleted]]
Le 30/09/2019 ? 16:17, Duncan Murdoch a ?crit?:> > There's a StackOverflow question > https://stackoverflow.com/q/22024082/2554330 that references this text > from ?missing: > > "Currently missing can only be used in the immediate body of the > function that defines the argument, not in the body of a nested > function or a local call. This may change in the future." > > Someone pointed out (in https://stackoverflow.com/a/58169498/2554330) > that this isn't true in the examples they've tried:? missingness does > get passed along.? This example shows it (this is slightly different > than the SO example): > > f1 <- function(x, y, z){ > ? if(missing(x)) > ??? cat("f1: x is missing\n") > ? if(missing(y)) > ??? cat("f1: y is missing\n") > } > > f2 <- function(x, y, z){ > ? if(missing(z)) > ??? cat("f2: z is missing\n") > ? f1(x, y) > } > > f2() > > which produces > > f2: z is missing > f1: x is missing > f1: y is missing > > Is the documentation out of date?? That quote appears to have been > written in 2002.Er, as far? as I understand the cited doc, it correctly describes what happened in your example: missing() is not working in a local call (here f1(x,y)). In fact, what missing() of f1 is reporting it is still the situation of f2() call (i.e. immediate body of the function). See f2(y=1) produces f2: z is missing f1: x is missing (the line about y missing disappeared from f1(x,y) call, what needed to be demonstrated). Best, Serguei.
On 01/10/2019 4:58 a.m., Serguei Sokol wrote:> Le 30/09/2019 ? 16:17, Duncan Murdoch a ?crit?: >> >> There's a StackOverflow question >> https://stackoverflow.com/q/22024082/2554330 that references this text >> from ?missing: >> >> "Currently missing can only be used in the immediate body of the >> function that defines the argument, not in the body of a nested >> function or a local call. This may change in the future." >> >> Someone pointed out (in https://stackoverflow.com/a/58169498/2554330) >> that this isn't true in the examples they've tried:? missingness does >> get passed along.? This example shows it (this is slightly different >> than the SO example): >> >> f1 <- function(x, y, z){ >> ? if(missing(x)) >> ??? cat("f1: x is missing\n") >> ? if(missing(y)) >> ??? cat("f1: y is missing\n") >> } >> >> f2 <- function(x, y, z){ >> ? if(missing(z)) >> ??? cat("f2: z is missing\n") >> ? f1(x, y) >> } >> >> f2() >> >> which produces >> >> f2: z is missing >> f1: x is missing >> f1: y is missing >> >> Is the documentation out of date?? That quote appears to have been >> written in 2002. > Er, as far? as I understand the cited doc, it correctly describes what > happened in your example: missing() is not working in a local call (here > f1(x,y)). > In fact, what missing() of f1 is reporting it is still the situation of > f2() call (i.e. immediate body of the function). See > > f2(y=1) > > produces > > f2: z is missing > f1: x is missing > > (the line about y missing disappeared from f1(x,y) call, what needed to > be demonstrated).Yes, that's a possible interpretation. Another one is that missing should fail in this example: f2 <- function(z){ f1 <- function(){ if(missing(z)) cat("f1: z is missing\n") } f1() } and it does: > f2() Error in missing(z) (from #3) : 'missing' can only be used for arguments Here missing() is appearing in a nested function. I'm really not sure which is the intended meaning of that paragraph: what exactly is a "local call"? Duncan Murdoch
Le 01/10/2019 ? 10:58, Serguei Sokol a ?crit?:> Le 30/09/2019 ? 16:17, Duncan Murdoch a ?crit?: >> >> There's a StackOverflow question >> https://stackoverflow.com/q/22024082/2554330 that references this >> text from ?missing: >> >> "Currently missing can only be used in the immediate body of the >> function that defines the argument, not in the body of a nested >> function or a local call. This may change in the future." >> >> Someone pointed out (in https://stackoverflow.com/a/58169498/2554330) >> that this isn't true in the examples they've tried:? missingness does >> get passed along.? This example shows it (this is slightly different >> than the SO example): >> >> f1 <- function(x, y, z){ >> ? if(missing(x)) >> ??? cat("f1: x is missing\n") >> ? if(missing(y)) >> ??? cat("f1: y is missing\n") >> } >> >> f2 <- function(x, y, z){ >> ? if(missing(z)) >> ??? cat("f2: z is missing\n") >> ? f1(x, y) >> } >> >> f2() >> >> which produces >> >> f2: z is missing >> f1: x is missing >> f1: y is missing >> >> Is the documentation out of date?? That quote appears to have been >> written in 2002. > Er, as far? as I understand the cited doc, it correctly describes what > happened in your example: missing() is not working in a local call > (here f1(x,y)). > In fact, what missing() of f1 is reporting it is still the situation > of f2() call (i.e. immediate body of the function). See > > f2(y=1) > > produces > > f2: z is missing > f1: x is missing > > (the line about y missing disappeared from f1(x,y) call, what needed > to be demonstrated).Re-er, it seem that I was a little bit to fast in my conclusion. If we modify f2 to be f2 <- function(x, y, z){ ? if(missing(z)) ??? cat("f2: z is missing\n") ? f1(x=1, y) } then f2() call gives f2: z is missing f1: y is missing i.e. missing() of f1(x=1,y) call is reporting its own situation, not those of f2(). And the missingess of y seems to be inherited from f2() call. Sorry to be hasty. Serguei.