0

Let's define:

f <- function(x) deparse(substitute(x))

The challenge: find <something> so that f(<something>) returns "abc". Excluding, of course, f(abc).

With "tidy NSE", i.e. quasiquoting, this is very easy. However, according to the NSE references (1, 2, 3), it is impossible since substitute is a pure quoting (as opposed to quasiquoting) function.

I wonder if there is anything obscure or undocumented (not that uncommon!) that allows to unquote in substitute, hence the challenge.

asachet
  • 6,620
  • 2
  • 30
  • 74
  • 3
    No, there isn't. `x` is never evaluated. Thus, `f(abc)` is the only possible way to get this output. – Roland Oct 11 '19 at 16:16
  • 1
    What's the use case? What are you trying to do? Or is this just some obscure trivia challenge? – MrFlick Oct 11 '19 at 16:27
  • @MrFlick Obscure trivia challenge - I am not trying to hide it in the post! It was prompted by a recent question on SO about the programmatic use of a package that relies on deparse/substitute internally. Of course that was a bad choice from the package developer but I was wondering if there's really no way around it. – asachet Oct 11 '19 at 17:27

1 Answers1

1

@Roland is correct. Because x is not evaluated, there is no expression you can provide to f that won't be converted to a string verbatim. Quasiquotation in base R is handled by bquote(), which has a .() mechanism that works similarly to rlang's !!:

# Quasiquotation with base R
f1 <- function(x) bquote( .(substitute(x)) + 5 )


# Quasiquotation with rlang
f2 <- function(x) rlang::expr( !!rlang::enexpr(x) + 5 )

e1 <- f1(y)               # y + 5
e2 <- f2(y)               # y + 5
identical(e1, e2)         # TRUE
eval(e1, list(y=10))      # 15
Artem Sokolov
  • 13,196
  • 4
  • 43
  • 74