Okay, but what is a quosure?

rlang::quo(mtcars)
## <quosure>
## expr: ^mtcars
## env:  global
my_fun <- function(data) { print(rlang::quo(data)) }
my_fun(mtcars)
## <quosure>
## expr: ^data
## env:  0x55cc46e94ef0
  • A quosure has two parts:
    1. An expression (rlang::quo_get_expr())
    2. An environment (rlang::quo_get_env())
  • A quosure is:
    • callable: Evaluation produces a result (currently require rlang::eval_tidy())
    • hygienic: Evaluates in the tracked environment
    • maskable: “If evaluated in a data mask (currently only masks created with eval_tidy() or new_data_mask()), the mask comes first in scope before the quosure environment.”
  • Quosures are similar to promises for lazy evaluation, but quosures are repeatable and do not cache results
  • Constants have an empty environment due to the structure of base R

A bit borrowed from Advanced R:

  • Quosures are a subclass of formulas and are therefore call objects with an environment attribute