quosure with quo include the environment in which the variable should be evaluated. With expr, you just have the variable to be evaluated when called. A small example,
dummy_fun <- function(x, y = 3) {
res_enquo <- rlang::eval_tidy(to_print <- rlang::enquo(x))
message("When using quo/enquo, you have the environment:")
print(to_print)
res_enexpr <- rlang::eval_tidy(to_print <- rlang::enexpr(x))
message("When using expr/enexpr, you just have the symbol (or name):")
print(to_print)
message(glue::glue("Inside this function, y value is {y}",
"With enquo, results is : {res_enquo}",
"With enexpr, results is : {res_enexpr}",
.sep = "\n"))
}
# define a value of y outside d
y <- 2
dummy_fun(y, y = 10)
#> When using quo/enquo, you have the environment:
#> <quosure>
#> expr: ^y
#> env: global
#> When using expr/enexpr, you just have the symbol (or name):
#> y
#> Inside this function, y value is 10
#> With enquo, results is : 2
#> With enexpr, results is : 10
dummy_fun(y, y = 5)
#> When using quo/enquo, you have the environment:
#> <quosure>
#> expr: ^y
#> env: global
#> When using expr/enexpr, you just have the symbol (or name):
#> y
#> Inside this function, y value is 5
#> With enquo, results is : 2
#> With enexpr, results is : 5
You see that if you use enquo, you get the argument x content provided by the user + the environment associated. So I get y that I defined outside the function. When using enexpr, you get the content of x I provided, so y but no information on the environment associated. So when evaluated with eval_tidy here, (same with !!), it will be evaluated in the context of the function environment, where I defined voluntarily for example a y variable, that I defined by argument function.
So, when you know you'll want to get the quosure from the user argument to be evaluated as defined elsewhere by the user, you need quo. When you just need an expression or a symbol to be evaluated in the context you define yourself, you need enexpr. Hope it is clearer !
To help begin with tidyeval, there is friendlyeval
that help you program with dplyr, and transform easily with an RStudio addin to rlang code syntax.