vector_logic_linter: Enforce usage of scalar logical operators in conditional...

View source: R/vector_logic_linter.R

vector_logic_linterR Documentation

Enforce usage of scalar logical operators in conditional statements

Description

Usage of & in conditional statements is error-prone and inefficient. condition in if (condition) expr must always be of length 1, in which case && is to be preferred. Ditto for | vs. ||.

Usage

vector_logic_linter()

Details

This linter covers inputs to ⁠if()⁠ and ⁠while()⁠ conditions and to testthat::expect_true() and testthat::expect_false().

Note that because & and | are generics, it is possible that && / || are not perfect substitutes because & is doing method dispatch in an incompatible way.

Moreover, be wary of code that may have side effects, most commonly assignments. Consider if ((a <- foo(x)) | (b <- bar(y))) { ... } vs. if ((a <- foo(x)) || (b <- bar(y))) { ... }. Because || exits early, if a is TRUE, the second condition will never be evaluated and b will not be assigned. Such usage is not allowed by the Tidyverse style guide, and the code can easily be refactored by pulling the assignment outside the condition, so using || is still preferable.

Tags

best_practices, common_mistakes, default, efficiency

See Also

Examples

# will produce lints
lint(
  text = "if (TRUE & FALSE) 1",
  linters = vector_logic_linter()
)

lint(
  text = "if (TRUE && (TRUE | FALSE)) 4",
  linters = vector_logic_linter()
)

lint(
  text = "filter(x, A && B)",
  linters = vector_logic_linter()
)

# okay
lint(
  text = "if (TRUE && FALSE) 1",
  linters = vector_logic_linter()
)

lint(
  text = "if (TRUE && (TRUE || FALSE)) 4",
  linters = vector_logic_linter()
)

lint(
  text = "filter(x, A & B)",
  linters = vector_logic_linter()
)


jimhester/lintr documentation built on April 24, 2024, 8:21 a.m.