While all capturing functions in the tidy evaluation framework perform unquote on capture (most notably quo()), expr_interp() manually processes unquoting operators in expressions that are already captured. expr_interp() should be called in all user-facing functions expecting a formula as argument to provide the same quasiquotation functionality as NSE functions.

expr_interp(x, env = NULL)

Arguments

x

A function, raw expression, or formula to interpolate.

env

The environment in which unquoted expressions should be evaluated. By default, the formula or closure environment if a formula or a function, or the current environment otherwise.

Examples

# All tidy NSE functions like quo() unquote on capture:
quo(list(!!(1 + 2)))
#> <quosure>
#> expr: ^list(3)
#> env:  0x560eb0833ef8

# expr_interp() is meant to provide the same functionality when you
# have a formula or expression that might contain unquoting
# operators:
f <- ~list(!!(1 + 2))
expr_interp(f)
#> ~list(3)
#> <environment: 0x560eb0833ef8>

# Note that only the outer formula is unquoted (which is a reason
# to use expr_interp() as early as possible in all user-facing
# functions):
f <- ~list(~!!(1 + 2), !!(1 + 2))
expr_interp(f)
#> ~list(~3, 3)
#> <environment: 0x560eb0833ef8>


# Another purpose for expr_interp() is to interpolate a closure's
# body. This is useful to inline a function within another. The
# important limitation is that all formal arguments of the inlined
# function should be defined in the receiving function:
other_fn <- function(x) toupper(x)

fn <- expr_interp(function(x) {
  x <- paste0(x, "_suffix")
  !!! body(other_fn)
})
#> Warning: Unquoting language objects with `!!!` is deprecated as of rlang 0.4.0.
#> Please use `!!` instead.
#> 
#>   # Bad:
#>   dplyr::select(data, !!!enquo(x))
#> 
#>   # Good:
#>   dplyr::select(data, !!enquo(x))    # Unquote single quosure
#>   dplyr::select(data, !!!enquos(x))  # Splice list of quosures
#> 
#> This warning is displayed once per session.
fn
#> function (x) 
#> {
#>     x <- paste0(x, "_suffix")
#>     toupper(x)
#> }
#> <environment: 0x560eb0833ef8>
fn("foo")
#> [1] "FOO_SUFFIX"