1

Define an expression

> xy <- expr(x+y)

Use it to build a second expression ... and it works

> expr(a + !!xy)

a + (x + y)

simply changing the order of the arguments and it stops working

> expr(!!xy + a)
Error in (function (x)  : object 'a' not found

Am I missing something?

Thanks

Andrea
  • 593
  • 2
  • 8

1 Answers1

1

There is way to make it work. Change the way !!xy has been used in expr and it will work. i.e

expr((!!xy) + a)

#(x + y) + a

The reason is that priority of all arithmetic and comparison operators are higher than !. Hence arithmetic and comparison operators binds tightly than !. e.g.:

> expr(!!2 + 3)
[1] 5
> expr((!!2) + 3)
(2) + 3

The r-documentation for quasiquotation has clearly mentioned it as:

# The !! operator is a handy syntactic shortcut for unquoting with
# UQ().  However you need to be a bit careful with operator
# precedence. All arithmetic and comparison operators bind more
# tightly than `!`:
quo(1 +  !! (1 + 2 + 3) + 10)

# For this reason you should always wrap the unquoted expression
# with parentheses when operators are involved:
quo(1 + (!! 1 + 2 + 3) + 10)

# Or you can use the explicit unquote function:
quo(1 + UQ(1 + 2 + 3) + 10)
MKR
  • 19,739
  • 4
  • 23
  • 33
  • Thanks a lot for your replay Have you any reference where all of this is explained? – Andrea Mar 04 '18 at 23:51
  • @Andrea The reason is simple. The `!!` is shortcut of `UQ`. Operator precedence-wise `!!` is applied `after` arithmetic-operators. Hence it is advised to wrap the unquoted expression with parentheses. I'm updating my answer with link of reference – MKR Mar 05 '18 at 06:08
  • @Andrea Have a look at updated answer. If it clarifies your query then you can accept answer so that it will be helpful to future user. – MKR Mar 05 '18 at 09:58
  • 1
    Thanks @MRK your comments have been very usefull – Andrea Mar 05 '18 at 22:43