1#' Defuse R expressions 2#' 3#' @description 4#' 5#' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("stable")} 6#' 7#' The defusing operators `expr()` and `enquo()` prevent the 8#' evaluation of R code. Defusing is also known as _quoting_, and is 9#' done in base R by [quote()] and [substitute()]. When a function 10#' argument is defused, R doesn't return its value like it normally 11#' would but it returns the R expression describing how to make the 12#' value. These defused expressions are like blueprints for computing 13#' values. 14#' 15#' There are two main ways to defuse expressions, to which correspond 16#' the two functions `expr()` and `enquo()`. Whereas `expr()` defuses 17#' your own expression, `enquo()` defuses expressions supplied as 18#' argument by the user of a function. See section on function 19#' arguments for more on this distinction. 20#' 21#' The main purpose of defusing evaluation of an expression is to 22#' enable data-masking, where an expression is evaluated in the 23#' context of a data frame so that you can write `var` instead of 24#' `data$var`. The expression is defused so it can be resumed later 25#' on, in a context where the data-variables have been defined. 26#' 27#' Defusing prevents the evaluation of R code, but you can still force 28#' evaluation inside a defused expression with the [forcing 29#' operators][nse-force] `!!` and `!!!`. 30#' 31#' 32#' @section Types of defused expressions: 33#' 34#' * __Calls__, like `f(1, 2, 3)` or `1 + 1` represent the action of 35#' calling a function to compute a new value, such as a vector. 36#' 37#' * __Symbols__, like `x` or `df`, represent named objects. When the 38#' object pointed to by the symbol was defined in a function or in 39#' the global environment, we call it an environment-variable. When 40#' the object is a column in a data frame, we call it a 41#' data-variable. 42#' 43#' You can create new call or symbol objects by using the defusing 44#' function `expr()`: 45#' 46#' ``` 47#' # Create a symbol representing objects called `foo` 48#' expr(foo) 49#' 50#' # Create a call representing the computation of the mean of `foo` 51#' expr(mean(foo, na.rm = TRUE)) 52#' ``` 53#' 54#' Defusing is not the only way to create defused expressions. You can 55#' also assemble them from data: 56#' 57#' ``` 58#' # Assemble a symbol from a string 59#' var <- "foo" 60#' sym(var) 61#' 62#' # Assemble a call from strings, symbols, and other objects 63#' call("mean", sym(var), na.rm = TRUE) 64#' ``` 65#' 66#' 67#' @section Defusing function arguments: 68#' 69#' There are two points of view when it comes to defusing an 70#' expression: 71#' 72#' * You can defuse expressions that _you_ supply with `expr()`. This 73#' is one way of creating symbols and calls (see previous section). 74#' 75#' * You can defuse the expressions supplied by _the user_ of your 76#' function with the operators starting with `en` like `ensym()`, 77#' `enquo()` and their plural variants. They defuse function 78#' arguments . 79#' 80#' 81#' @section Defused arguments and quosures: 82#' 83#' If you inspect the return values of `expr()` and `enquo()`, you'll 84#' notice that the latter doesn't return a raw expression like the 85#' former. Instead it returns a __quosure__, a wrapper containing an 86#' expression and an environment. R needs information about the 87#' environment to properly evaluate the argument expression because it 88#' comes from a different context than the current function. 89#' 90#' See the [quosure] help topic about tools to work with quosures. 91#' 92#' 93#' @section Comparison to base R: 94#' 95#' * The defusing operator `expr()` is similar to [quote()]. Like 96#' [bquote()], it allows [forcing][nse-defuse] evaluation of parts 97#' of an expression. 98#' 99#' * The plural variant `exprs()` is similar to [alist()]. 100#' 101#' * The argument-defusing operator `enquo()` is similar to 102#' [substitute()]. 103#' 104#' @inheritParams dots_list 105#' @param expr An expression. 106#' @param arg A symbol representing an argument. The expression 107#' supplied to that argument will be captured instead of being 108#' evaluated. 109#' @param ... For `enexprs()`, `ensyms()` and `enquos()`, names of 110#' arguments to capture without evaluation (including `...`). For 111#' `exprs()` and `quos()`, the expressions to capture unevaluated 112#' (including expressions contained in `...`). 113#' @param .ignore_empty Whether to ignore empty arguments. Can be one 114#' of `"trailing"`, `"none"`, `"all"`. If `"trailing"`, only the 115#' last argument is ignored if it is empty. Note that `"trailing"` 116#' applies only to arguments passed in `...`, not to named 117#' arguments. On the other hand, `"all"` also applies to named 118#' arguments. 119#' @param .unquote_names Whether to treat `:=` as `=`. Unlike `=`, the 120#' `:=` syntax supports `!!` unquoting on the LHS. 121#' @name nse-defuse 122#' @aliases quotation 123#' @seealso [enquo0()] and [enquos0()] for variants that do not 124#' perform automatic injection/unquotation. 125#' @examples 126#' # expr() and exprs() capture expressions that you supply: 127#' expr(symbol) 128#' exprs(several, such, symbols) 129#' 130#' # enexpr() and enexprs() capture expressions that your user supplied: 131#' expr_inputs <- function(arg, ...) { 132#' user_exprs <- enexprs(arg, ...) 133#' user_exprs 134#' } 135#' expr_inputs(hello) 136#' expr_inputs(hello, bonjour, ciao) 137#' 138#' # ensym() and ensyms() provide additional type checking to ensure 139#' # the user calling your function has supplied bare object names: 140#' sym_inputs <- function(...) { 141#' user_symbols <- ensyms(...) 142#' user_symbols 143#' } 144#' sym_inputs(hello, "bonjour") 145#' ## sym_inputs(say(hello)) # Error: Must supply symbols or strings 146#' expr_inputs(say(hello)) 147#' 148#' 149#' # All these quoting functions have quasiquotation support. This 150#' # means that you can unquote (evaluate and inline) part of the 151#' # captured expression: 152#' what <- sym("bonjour") 153#' expr(say(what)) 154#' expr(say(!!what)) 155#' 156#' # This also applies to expressions supplied by the user. This is 157#' # like an escape hatch that allows control over the captured 158#' # expression: 159#' expr_inputs(say(!!what), !!what) 160#' 161#' 162#' # Finally, you can capture expressions as quosures. A quosure is an 163#' # object that contains both the expression and its environment: 164#' quo <- quo(letters) 165#' quo 166#' 167#' get_expr(quo) 168#' get_env(quo) 169#' 170#' # Quosures can be evaluated with eval_tidy(): 171#' eval_tidy(quo) 172#' 173#' # They have the nice property that you can pass them around from 174#' # context to context (that is, from function to function) and they 175#' # still evaluate in their original environment: 176#' multiply_expr_by_10 <- function(expr) { 177#' # We capture the user expression and its environment: 178#' expr <- enquo(expr) 179#' 180#' # Then create an object that only exists in this function: 181#' local_ten <- 10 182#' 183#' # Now let's create a multiplication expression that (a) inlines 184#' # the user expression as LHS (still wrapped in its quosure) and 185#' # (b) refers to the local object in the RHS: 186#' quo(!!expr * local_ten) 187#' } 188#' quo <- multiply_expr_by_10(2 + 3) 189#' 190#' # The local parts of the quosure are printed in colour if your 191#' # terminal is capable of displaying colours: 192#' quo 193#' 194#' # All the quosures in the expression evaluate in their original 195#' # context. The local objects are looked up properly and we get the 196#' # expected result: 197#' eval_tidy(quo) 198NULL 199 200#' @rdname nse-defuse 201#' @export 202expr <- function(expr) { 203 enexpr(expr) 204} 205#' @rdname nse-defuse 206#' @export 207enexpr <- function(arg) { 208 .Call(rlang_enexpr, substitute(arg), parent.frame()) 209} 210 211#' @rdname nse-defuse 212#' @export 213exprs <- function(..., 214 .named = FALSE, 215 .ignore_empty = c("trailing", "none", "all"), 216 .unquote_names = TRUE) { 217 .Call(rlang_exprs_interp, 218 frame_env = environment(), 219 named = .named, 220 ignore_empty = .ignore_empty, 221 unquote_names = .unquote_names, 222 homonyms = "keep", 223 check_assign = FALSE 224 ) 225} 226#' @rdname nse-defuse 227#' @export 228enexprs <- function(..., 229 .named = FALSE, 230 .ignore_empty = c("trailing", "none", "all"), 231 .unquote_names = TRUE, 232 .homonyms = c("keep", "first", "last", "error"), 233 .check_assign = FALSE) { 234 endots( 235 call = sys.call(), 236 frame_env = parent.frame(), 237 capture_arg = rlang_enexpr, 238 capture_dots = rlang_exprs_interp, 239 named = .named, 240 ignore_empty = .ignore_empty, 241 unquote_names = .unquote_names, 242 homonyms = .homonyms, 243 check_assign = .check_assign 244 ) 245} 246 247#' @rdname nse-defuse 248#' @export 249ensym <- function(arg) { 250 .Call(rlang_ensym, substitute(arg), parent.frame()) 251} 252#' @rdname nse-defuse 253#' @export 254ensyms <- function(..., 255 .named = FALSE, 256 .ignore_empty = c("trailing", "none", "all"), 257 .unquote_names = TRUE, 258 .homonyms = c("keep", "first", "last", "error"), 259 .check_assign = FALSE) { 260 exprs <- endots( 261 call = sys.call(), 262 frame_env = parent.frame(), 263 capture_arg = rlang_enexpr, 264 capture_dots = rlang_exprs_interp, 265 named = .named, 266 ignore_empty = .ignore_empty, 267 unquote_names = .unquote_names, 268 homonyms = .homonyms, 269 check_assign = .check_assign 270 ) 271 map(exprs, function(expr) { 272 if (is_quosure(expr)) { 273 expr <- quo_get_expr(expr) 274 } 275 sym(expr) 276 }) 277} 278 279 280#' @rdname nse-defuse 281#' @export 282quo <- function(expr) { 283 enquo(expr) 284} 285#' @rdname nse-defuse 286#' @export 287enquo <- function(arg) { 288 .Call(rlang_enquo, substitute(arg), parent.frame()) 289} 290 291#' @rdname nse-defuse 292#' @export 293quos <- function(..., 294 .named = FALSE, 295 .ignore_empty = c("trailing", "none", "all"), 296 .unquote_names = TRUE) { 297 .Call(rlang_quos_interp, 298 frame_env = environment(), 299 named = .named, 300 ignore_empty = .ignore_empty, 301 unquote_names = .unquote_names, 302 homonyms = "keep", 303 check_assign = FALSE 304 ) 305} 306#' @rdname nse-defuse 307#' @export 308enquos <- function(..., 309 .named = FALSE, 310 .ignore_empty = c("trailing", "none", "all"), 311 .unquote_names = TRUE, 312 .homonyms = c("keep", "first", "last", "error"), 313 .check_assign = FALSE) { 314 quos <- endots( 315 call = sys.call(), 316 frame_env = parent.frame(), 317 capture_arg = rlang_enquo, 318 capture_dots = rlang_quos_interp, 319 named = .named, 320 ignore_empty = .ignore_empty, 321 unquote_names = .unquote_names, 322 homonyms = .homonyms, 323 check_assign = .check_assign 324 ) 325 structure(quos, class = c("quosures", "list")) 326} 327 328 329capture_args <- c( 330 ".named", 331 ".ignore_empty", 332 ".unquote_names", 333 ".homonyms", 334 ".check_assign" 335) 336 337endots <- function(call, 338 frame_env, 339 capture_arg, 340 capture_dots, 341 named, 342 ignore_empty, 343 unquote_names, 344 homonyms, 345 check_assign) { 346 ignore_empty <- arg_match0(ignore_empty, c("trailing", "none", "all")) 347 syms <- as.list(node_cdr(call)) 348 349 if (!is_null(names(syms))) { 350 is_arg <- names(syms) %in% capture_args 351 syms <- syms[!is_arg] 352 } 353 354 # Avoid note about registration problems 355 dot_call <- .Call 356 357 splice_dots <- FALSE 358 dots <- map(syms, function(sym) { 359 if (!is_symbol(sym)) { 360 abort("Inputs to capture must be argument names") 361 } 362 if (identical(sym, dots_sym)) { 363 splice_dots <<- TRUE 364 splice(dot_call(capture_dots, 365 frame_env = frame_env, 366 named = named, 367 ignore_empty = ignore_empty, 368 unquote_names = unquote_names, 369 homonyms = homonyms, 370 check_assign = check_assign 371 )) 372 } else { 373 dot_call(capture_arg, sym, frame_env) 374 } 375 }) 376 377 if (splice_dots) { 378 dots <- flatten_if(dots, is_spliced) 379 } 380 381 if (ignore_empty == "all") { 382 if (identical(capture_arg, rlang_enquo)) { 383 dot_is_missing <- quo_is_missing 384 } else { 385 dot_is_missing <- is_missing 386 } 387 dots <- keep(dots, negate(dot_is_missing)) 388 } 389 390 if (named) { 391 dots <- quos_auto_name(dots) 392 } 393 names(dots) <- names2(dots) 394 395 dots 396} 397 398#' Ensure that all elements of a list of expressions are named 399#' 400#' This gives default names to unnamed elements of a list of 401#' expressions (or expression wrappers such as formulas or 402#' quosures). `exprs_auto_name()` deparses the expressions with 403#' [expr_name()] by default. `quos_auto_name()` deparses with 404#' [quo_name()]. 405#' 406#' @param exprs A list of expressions. 407#' @param width Deprecated. Maximum width of names. 408#' @param printer Deprecated. A function that takes an expression 409#' and converts it to a string. This function must take an 410#' expression as the first argument and `width` as the second 411#' argument. 412#' @export 413exprs_auto_name <- function(exprs, width = NULL, printer = NULL) { 414 if (!is_null(width)) { 415 warn_deprecated(paste_line( 416 "The `width` argument is deprecated as of rlang 0.3.0." 417 )) 418 } 419 420 if (!is_null(printer)) { 421 warn_deprecated(paste_line( 422 "The `printer` argument is deprecated as of rlang 0.3.0." 423 )) 424 } 425 426 have_name <- have_name(exprs) 427 if (any(!have_name)) { 428 nms <- map_chr(exprs[!have_name], as_label) 429 names(exprs)[!have_name] <- nms 430 } 431 432 exprs 433} 434#' @rdname exprs_auto_name 435#' @param quos A list of quosures. 436#' @export 437quos_auto_name <- function(quos, width = NULL) { 438 exprs_auto_name(quos, width = width) 439} 440 441 442captureArgInfo <- function(arg) { 443 .External(rlang_ext_capturearginfo, environment(), parent.frame()) 444} 445captureDots <- function() { 446 .External(rlang_ext_capturedots, parent.frame()) 447} 448 449 450#' Defuse arguments without automatic injection 451#' 452#' The 0-suffixed variants of [enquo()] and [enquos()] defuse function 453#' arguments without automatic injection (unquotation). They are 454#' useful when defusing expressions that potentially include `!!`, 455#' `!!!`, or `{{` operations, for instance tidyverse code. In that 456#' case, `enquo()` would process these operators too early, creating a 457#' confusing experience for users. Callers can still inject objects 458#' or expressions using manual injection with [inject()]. 459#' 460#' None of the features of [dynamic dots][dyn-dots] are available when 461#' defusing with `enquos0()`. For instance, trailing empty arguments 462#' are not automatically trimmed. 463#' 464#' @param arg A symbol for a function argument to defuse. 465#' @param ... Dots to defuse. 466#' 467#' @seealso [enquo()] and [enquos()] 468#' @examples 469#' automatic_injection <- function(x) enquo(x) 470#' no_injection <- function(x) enquo0(x) 471#' 472#' automatic_injection(foo(!!!1:3)) 473#' no_injection(foo(!!!1:3)) 474#' @export 475enquo0 <- function(arg) { 476 info <- .External(rlang_ext_capturearginfo, environment(), parent.frame()) 477 as_quosure(info$expr, info$env) 478} 479#' @rdname enquo0 480#' @export 481enquos0 <- function(...) { 482 dots <- .External(rlang_ext_capturedots, environment()) 483 lapply(dots, function(dot) as_quosure(dot$expr, dot$env)) 484} 485