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