1#' Force parts of an expression 2#' 3#' @description 4#' 5#' It is sometimes useful to force early evaluation of part of an 6#' expression before it gets fully evaluated. The tidy eval framework 7#' provides several forcing operators for different use cases. 8#' 9#' - The bang-bang operator `!!` forces a _single_ object. One 10#' common case for `!!` is to substitute an environment-variable 11#' (created with `<-`) with a data-variable (inside a data frame). 12#' 13#' ``` 14#' library(dplyr) 15#' 16#' # The environment variable `var` refers to the data-variable 17#' # `height` 18#' var <- sym("height") 19#' 20#' # We force `var`, which substitutes it with `height` 21#' starwars %>% 22#' summarise(avg = mean(!!var, na.rm = TRUE)) 23#' ``` 24#' 25#' - The big-bang operator `!!!` forces-splice a _list_ of objects. 26#' The elements of the list are spliced in place, meaning that they 27#' each become one single argument. 28#' 29#' ``` 30#' vars <- syms(c("height", "mass")) 31#' 32#' # Force-splicing is equivalent to supplying the elements separately 33#' starwars %>% select(!!!vars) 34#' starwars %>% select(height, mass) 35#' ``` 36#' 37#' - The curly-curly operator `{{ }}` for function arguments is a bit 38#' special because it forces the function argument and immediately 39#' defuses it. The defused expression is substituted in place, ready 40#' to be evaluated in another context, such as the data frame. 41#' 42#' In practice, this is useful when you have a data-variable in an 43#' env-variable (such as a function argument). 44#' 45#' ``` 46#' # Force-defuse all function arguments that might contain 47#' # data-variables by embracing them with {{ }} 48#' mean_by <- function(data, by, var) { 49#' data %>% 50#' group_by({{ by }}) %>% 51#' summarise(avg = mean({{ var }}, na.rm = TRUE)) 52#' } 53#' 54#' # The env-variables `by` and `var` are forced but defused. 55#' # The data-variables they contain are evaluated by dplyr later on 56#' # in data context. 57#' iris %>% mean_by(by = Species, var = Sepal.Width) 58#' ``` 59#' 60#' Use `qq_show()` to experiment with forcing operators. `qq_show()` 61#' defuses its input, processes all forcing operators, and prints the 62#' result with [expr_print()] to reveal objects inlined in the 63#' expression by the forcing operators. 64#' 65#' 66#' @section Forcing names: 67#' 68#' When a function takes multiple named arguments 69#' (e.g. `dplyr::mutate()`), it is difficult to supply a variable as 70#' name. Since the LHS of `=` is [defused][nse-defuse], giving the name 71#' of a variable results in the argument having the name of the 72#' variable rather than the name stored in that variable. This problem 73#' of forcing evaluation of names is exactly what the `!!` operator is 74#' for. 75#' 76#' Unfortunately R is very strict about the kind of expressions 77#' supported on the LHS of `=`. This is why rlang interprets the 78#' walrus operator `:=` as an alias of `=`. You can use it to supply 79#' names, e.g. `a := b` is equivalent to `a = b`. Since its syntax is 80#' more flexible you can also force names on its LHS: 81#' 82#' ``` 83#' name <- "Jane" 84#' 85#' list2(!!name := 1 + 2) 86#' exprs(!!name := 1 + 2) 87#' ``` 88#' 89#' Like `=`, the `:=` operator expects strings or symbols on its LHS. 90#' 91#' Since unquoting names is related to interpolating within a string 92#' with the glue package, we have made the glue syntax available on 93#' the LHS of `:=`: 94#' 95#' ``` 96#' list2("{name}" := 1) 97#' tibble("{name}" := 1) 98#' ``` 99#' 100#' You can also interpolate defused function arguments with double 101#' braces `{{`, similar to the curly-curly syntax: 102#' 103#' ``` 104#' wrapper <- function(data, var) { 105#' data %>% mutate("{{ var }}_foo" := {{ var }} * 2) 106#' } 107#' ``` 108#' 109#' Currently, forcing names with `:=` only works in top level 110#' expressions. These are all valid: 111#' 112#' ``` 113#' exprs("{name}" := x) 114#' tibble("{name}" := x) 115#' ``` 116#' 117#' But deep-forcing names isn't supported: 118#' 119#' ``` 120#' exprs(this(is(deep("{name}" := x)))) 121#' ``` 122#' 123#' 124#' @section Theory: 125#' 126#' Formally, `quo()` and `expr()` are quasiquotation functions, `!!` 127#' is the unquote operator, and `!!!` is the unquote-splice operator. 128#' These terms have a rich history in Lisp languages, and live on in 129#' modern languages like 130#' [Julia](https://docs.julialang.org/en/v1/manual/metaprogramming/) 131#' and 132#' [Racket](https://docs.racket-lang.org/reference/quasiquote.html). 133#' 134#' 135#' @section Life cycle: 136#' 137#' * Calling `UQ()` and `UQS()` with the rlang namespace qualifier is 138#' deprecated as of rlang 0.3.0. Just use the unqualified forms 139#' instead: 140#' 141#' ``` 142#' # Bad 143#' rlang::expr(mean(rlang::UQ(var) * 100)) 144#' 145#' # Ok 146#' rlang::expr(mean(UQ(var) * 100)) 147#' 148#' # Good 149#' rlang::expr(mean(!!var * 100)) 150#' ``` 151#' 152#' Supporting namespace qualifiers complicates the implementation of 153#' unquotation and is misleading as to the nature of unquoting 154#' operators (which are syntactic operators that operate at 155#' quotation-time rather than function calls at evaluation-time). 156#' 157#' * `UQ()` and `UQS()` were soft-deprecated in rlang 0.2.0 in order 158#' to make the syntax of quasiquotation more consistent. The prefix 159#' forms are now \code{`!!`()} and \code{`!!!`()} which is 160#' consistent with other R operators (e.g. \code{`+`(a, b)} is the 161#' prefix form of `a + b`). 162#' 163#' Note that the prefix forms are not as relevant as before because 164#' `!!` now has the right operator precedence, i.e. the same as 165#' unary `-` or `+`. It is thus safe to mingle it with other 166#' operators, e.g. `!!a + !!b` does the right thing. In addition the 167#' parser now strips one level of parentheses around unquoted 168#' expressions. This way `(!!"foo")(...)` expands to `foo(...)`. 169#' These changes make the prefix forms less useful. 170#' 171#' Finally, the named functional forms `UQ()` and `UQS()` were 172#' misleading because they suggested that existing knowledge about 173#' functions is applicable to quasiquotation. This was reinforced by 174#' the visible definitions of these functions exported by rlang and 175#' by the tidy eval parser interpreting `rlang::UQ()` as `!!`. In 176#' reality unquoting is *not* a function call, it is a syntactic 177#' operation. The operator form makes it clearer that unquoting is 178#' special. 179#' 180#' @name nse-force 181#' @aliases quasiquotation UQ UQS {{}} \{\{ 182#' @examples 183#' # Interpolation with {{ }} is the easiest way to forward 184#' # arguments to tidy eval functions: 185#' if (is_attached("package:dplyr")) { 186#' 187#' # Forward all arguments involving data frame columns by 188#' # interpolating them within other data masked arguments. 189#' # Here we interpolate `arg` in a `summarise()` call: 190#' my_function <- function(data, arg) { 191#' summarise(data, avg = mean({{ arg }}, na.rm = TRUE)) 192#' } 193#' 194#' my_function(mtcars, cyl) 195#' my_function(mtcars, cyl * 10) 196#' 197#' # The operator is just a shortcut for `!!enquo()`: 198#' my_function <- function(data, arg) { 199#' summarise(data, avg = mean(!!enquo(arg), na.rm = TRUE)) 200#' } 201#' 202#' my_function(mtcars, cyl) 203#' 204#' } 205#' 206#' # Quasiquotation functions quote expressions like base::quote() 207#' quote(how_many(this)) 208#' expr(how_many(this)) 209#' quo(how_many(this)) 210#' 211#' # In addition, they support unquoting. Let's store symbols 212#' # (i.e. object names) in variables: 213#' this <- sym("apples") 214#' that <- sym("oranges") 215#' 216#' # With unquotation you can insert the contents of these variables 217#' # inside the quoted expression: 218#' expr(how_many(!!this)) 219#' expr(how_many(!!that)) 220#' 221#' # You can also insert values: 222#' expr(how_many(!!(1 + 2))) 223#' quo(how_many(!!(1 + 2))) 224#' 225#' 226#' # Note that when you unquote complex objects into an expression, 227#' # the base R printer may be a bit misleading. For instance compare 228#' # the output of `expr()` and `quo()` (which uses a custom printer) 229#' # when we unquote an integer vector: 230#' expr(how_many(!!(1:10))) 231#' quo(how_many(!!(1:10))) 232#' 233#' # This is why it's often useful to use qq_show() to examine the 234#' # result of unquotation operators. It uses the same printer as 235#' # quosures but does not return anything: 236#' qq_show(how_many(!!(1:10))) 237#' 238#' 239#' # Use `!!!` to add multiple arguments to a function. Its argument 240#' # should evaluate to a list or vector: 241#' args <- list(1:3, na.rm = TRUE) 242#' quo(mean(!!!args)) 243#' 244#' # You can combine the two 245#' var <- quote(xyz) 246#' extra_args <- list(trim = 0.9, na.rm = TRUE) 247#' quo(mean(!!var , !!!extra_args)) 248#' 249#' 250#' # The plural versions have support for the `:=` operator. 251#' # Like `=`, `:=` creates named arguments: 252#' quos(mouse1 := bernard, mouse2 = bianca) 253#' 254#' # The `:=` is mainly useful to unquote names. Unlike `=` it 255#' # supports `!!` on its LHS: 256#' var <- "unquote me!" 257#' quos(!!var := bernard, mouse2 = bianca) 258#' 259#' 260#' # All these features apply to dots captured by enquos(): 261#' fn <- function(...) enquos(...) 262#' fn(!!!args, !!var := penny) 263#' 264#' 265#' # Unquoting is especially useful for building an expression by 266#' # expanding around a variable part (the unquoted part): 267#' quo1 <- quo(toupper(foo)) 268#' quo1 269#' 270#' quo2 <- quo(paste(!!quo1, bar)) 271#' quo2 272#' 273#' quo3 <- quo(list(!!quo2, !!!syms(letters[1:5]))) 274#' quo3 275NULL 276 277#' @rdname nse-force 278#' @usage NULL 279#' @export 280UQ <- function(x) { 281 abort("`UQ()` can only be used within a quasiquoted argument") 282} 283#' @rdname nse-force 284#' @usage NULL 285#' @export 286UQS <- function(x) { 287 abort("`UQS()` can only be used within a quasiquoted argument") 288} 289#' @rdname nse-force 290#' @usage NULL 291#' @export 292`!!` <- function(x) { 293 abort("`!!` can only be used within a quasiquoted argument") 294} 295#' @rdname nse-force 296#' @usage NULL 297#' @export 298`!!!` <- function(x) { 299 abort("`!!!` can only be used within a quasiquoted argument") 300} 301#' @rdname nse-force 302#' @usage NULL 303#' @export 304`:=` <- function(x, y) { 305 abort("`:=` can only be used within a quasiquoted argument") 306} 307 308#' @rdname nse-force 309#' @param expr An expression to be quasiquoted. 310#' @export 311qq_show <- function(expr) { 312 expr_print(enexpr(expr)) 313} 314 315#' Process unquote operators in a captured expression 316#' 317#' While all capturing functions in the tidy evaluation framework 318#' perform unquote on capture (most notably [quo()]), 319#' `expr_interp()` manually processes unquoting operators in 320#' expressions that are already captured. `expr_interp()` should be 321#' called in all user-facing functions expecting a formula as argument 322#' to provide the same quasiquotation functionality as NSE functions. 323#' 324#' @param x A function, raw expression, or formula to interpolate. 325#' @param env The environment in which unquoted expressions should be 326#' evaluated. By default, the formula or closure environment if a 327#' formula or a function, or the current environment otherwise. 328#' @export 329#' @examples 330#' # All tidy NSE functions like quo() unquote on capture: 331#' quo(list(!!(1 + 2))) 332#' 333#' # expr_interp() is meant to provide the same functionality when you 334#' # have a formula or expression that might contain unquoting 335#' # operators: 336#' f <- ~list(!!(1 + 2)) 337#' expr_interp(f) 338#' 339#' # Note that only the outer formula is unquoted (which is a reason 340#' # to use expr_interp() as early as possible in all user-facing 341#' # functions): 342#' f <- ~list(~!!(1 + 2), !!(1 + 2)) 343#' expr_interp(f) 344#' 345#' 346#' # Another purpose for expr_interp() is to interpolate a closure's 347#' # body. This is useful to inline a function within another. The 348#' # important limitation is that all formal arguments of the inlined 349#' # function should be defined in the receiving function: 350#' other_fn <- function(x) toupper(x) 351#' 352#' fn <- expr_interp(function(x) { 353#' x <- paste0(x, "_suffix") 354#' !!! body(other_fn) 355#' }) 356#' fn 357#' fn("foo") 358expr_interp <- function(x, env = NULL) { 359 if (is_formula(x)) { 360 f_rhs(x) <- .Call(rlang_interp, f_rhs(x), env %||% f_env(x)) 361 } else if (is_closure(x)) { 362 body(x) <- .Call(rlang_interp, body(x), env %||% fn_env(x)) 363 } else { 364 x <- .Call(rlang_interp, x, env %||% parent.frame()) 365 } 366 x 367} 368 369 370glue_unquote <- function(text, env = caller_env()) { 371 glue::glue(glue_first_pass(text, env = env), .envir = env) 372} 373glue_first_pass <- function(text, env = caller_env()) { 374 glue::glue( 375 text, 376 .open = "{{", 377 .close = "}}", 378 .transformer = glue_first_pass_eval, 379 .envir = env 380 ) 381} 382glue_first_pass_eval <- function(text, env) { 383 text_expr <- parse_expr(text) 384 defused_expr <- eval_bare(call2(enexpr, text_expr), env) 385 as_label(defused_expr) 386} 387