-2

In R, there is the more general & and | that applies over a vector.

If you use && or ||, you will be exposed to bugs. So I can't think of a reason why we would use either of these.

  • 1
    Some info at https://stackoverflow.com/questions/6558921/boolean-operators-and – user20650 Apr 23 '21 at 19:04
  • 1
    > If you use && or ||, you will be exposed to bugs -- wat – Hong Ooi Apr 23 '21 at 19:48
  • Yeah you'll need to add some explanation how you think that exposes one to bugs. I mean I guess if you are under the impression that it's vectorized (which it's not and it states clearly that it isn't) then you'll be adding bugs but those operators don't automatically expose one to bugs. – Dason Apr 23 '21 at 19:57
  • 1
    @Dason, I think there's an argument in that direction in my answer (i.e., if arguments of length>1 are used with `&&`/`||` by accident, the behaviour is surprising (to me) - not *creating* bugs, but failing to flag a situation that could easily represent user error. By analogy, imagine if `if(x)` considered only the first element of `x` when `length(x)>1`, without warning. – Ben Bolker Apr 23 '21 at 23:53

2 Answers2

3

I feel like this is implicitly covered by Boolean operators && and || , but:

  • short-circuiting (i.e. the fact that in A && B, B is only evaluated if it needs to be; if A is FALSE then we know the result will be FALSE without evaluating B
    • improves efficiency
    • is particularly useful when trying to evaluate B would throw an error if A is FALSE (if we wanted to do this with & we would have to include some kind of try()/tryCatch() to handle that case)

I agree that the evaluation rule that &&/||

evaluate[s] left to right examining only the first element of each vector

(without even throwing a warning) seems odd and prone to produce unwanted/surprising results, i.e. if you accidentally use a vector of length>1 as part of a control statement. It would seem more natural to throw a warning or error in this case (e.g., the way that if() does if you give it a vector of length>1).

According to this tweet

It's a design bug in R; should really give error. There's work since R 3.6.0 (2019) to fix it. Until fixed, set _R_CHECK_LENGTH_1_LOGIC2_=true in your ~/.Renviron to get "Error in c(TRUE, TRUE) && c(TRUE, TRUE) : 'length(x) = 2 > 1' in coercion to 'logical(1)'"

(See this commit from 2018; this flag is used in CRAN checks.)

I don't know whether there is an (to me) obscure use case where this is convenient, or if it's for S compatibility. From Becker et al. 1988 The New S Language (via Google Books):

screenshot from Google books

Frustratingly, this does not explicitly define what happens if either cond1 or cond2 has length > 1 ...

Ben Bolker
  • 211,554
  • 25
  • 370
  • 453
2

The longer forms are intended for control statements where only a single logical value is allowed (even though more then one value is accepted with a warning). However, the longer forms only evaluate until the result is clear. Consider the following.

TRUE || FALSE

In this case, the FALSE does not have to be considered because the result is already clear from the TRUE. Consequently, the FALSE is not even evaluated. This is particularly useful if your second condition relies on the first condition being true because it would throw an error otherwise.

x <- "a"

if (is.numeric(x) & x/2 > 5) print(x)
if (is.numeric(x) && x/2 > 5) print(x)

The first case throws an error because you can't divide a character by a number. The second case will do just fine.

Ben Bolker
  • 211,554
  • 25
  • 370
  • 453
R. Schleutker
  • 131
  • 1
  • 4
  • And to add as to why that might be important imagine a long operation that might take a few minutes to run and then returns FALSE. If like in the example the first value was already true so you knew that the 'or' would evaluate to true you could skip that long operation and get a result immediately. – Dason Apr 23 '21 at 19:55