Skip to content

Discourage <<- ? #239

@MichaelChirico

Description

@MichaelChirico

{lintr} has long discouraged <<- as a default "undesirable operator":

https://github.com/r-lib/lintr/blob/50d9430173a9ed07570956e2a1de01c82fea9d93/R/zzz.R#L218-L223

Somehow I'd thought the Tidyverse guide also makes this ruling, but just found myself checking & realized there's no opinion.

I think avoiding <<- is good practice. The picture-perfect ideal usage looks like this:

w <- e <- NULL
tryCatch(
  foo(),
  warning = \(c) w <<- c,
  error = \(c) e <<- c
)

Here the target of <<- is maximally close in the code to where <<- is used. In any other case, it starts requiring a large mental load on the code reader to keep track of in which environment the LHS of <<- actually ends up getting assigned, and mistakes can cause really unexpected and hard-to-debug behavior (x <<- ..., where we meant y <<- ..., might wind up wiping out something important in some other environment).

These days I strongly encourage authors to be sometimes painfully explicit instead:

w <- e <- NULL
env <- environment()
tryCatch(
  foo(),
  warning = \(c) env$w <- c,
  error = \(c) env$e <- c
)

The code is slightly messier (we often wind up needing many more env$ qualifiers) but often easier to understand and maintain.

PS
The guide used to discourage pipe "in-place" assignment operator %<>%:

style/pipes.Rmd

Line 129 in 8de4bbc

The magrittr package provides the `%<>%` operator as a shortcut for modifying an object in place. Avoid this operator.

This advice was thrown out along with the move to only use the native pipe |> (#225). I believe the motivation for that advice would be similar to the proposed ruling here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions