14  Argument meaning should be independent

14.1 What’s the problem?

Avoid having one argument change the interpretation of another argument. This makes reading function calls harder because if the argument that changes meaning comes after the argument who’s meaning is changed you need to reinterpret the rest of the call.

14.2 What are some examples?

  • In library() the character.only argument changes how the package argument is interpreted:

    ggplot2 <- "dplyr"
    
    # Loads ggplot2
    library(ggplot2)
    
    # Loads dplyr
    library(ggplot2, character.only = TRUE)
  • In install.packages() setting repos = NULL changes the interpretation of pkgs from being a vector of package names to a vector of file paths.

  • In the base R string functions, perl and fixed change the interpretation of the pattern argument. See Section 17.3 for more details.

  • In ggplot2::geom_label(), setting parse = TRUE changes the meaning of the label argument/aesthetic from being any string to be a string on unparsed R code.

  • In readr::locale() there’s a complex dependency between decimal_mark and grouping_mark because they can’t be the same value, and Europe and the US Europe use different standards. That suggests it might have been better to specify them in a single argument like marks = c(",", ".").

  • In findInterval() if you set left.open = TRUE the rightmost.closed means leftmost.closed.

14.3 How do I remediate past mistakes?

Not clear that there’s a single solution. For the examples above:

  • In library(), I think this is an example of why base R needs a consistent mechanism for quoting and unquoting. If library() were a tidyverse function it would use tidy-eval, and so you’d write library(ggplot2) or library(!!ggplot2).

    Alternatively, you could maybe argue that it should be library("ggplot2") and library(ggplot2).

  • In install.packages() maybe it would be better to have mutually exclusive packages and paths arguments? Then repos only applies to paths which might suggest this is an example of the strategy pattern?

  • grepl() and friends are another example of the strategy pattern.

  • For ggplot2::geom_label() my gut feeling would be to make it another function, but parse = TRUE applies to geom_text() as well. So maybe the current setup is the least worst?

  • In findInterval() I think I’d fix it by renaming the argument to something that wasn’t direction specific. Maybe extemum.closed?