From lionel at rstudio.com  Wed Mar 22 20:17:39 2017
From: lionel at rstudio.com (Lionel Henry)
Date: Wed, 22 Mar 2017 20:17:39 +0100
Subject: [Rd] RFC: (in-principle) native unquoting for standard evaluation
In-Reply-To: <CAOQ5NyeF8fDYGwES0sy5eQfgFriK4Hos7vqX9R2YxkLgTPrhmg@mail.gmail.com>
References: <CAAjDRii1dPxNMTn9TSgReooOry2omQg9GCmXYDDFc99qv=F+7A@mail.gmail.com>
	<CAOQ5NydWHiqHkTVc=DHiQgqVkVqnoUN35EZYyQTwMJCWkap42A@mail.gmail.com>
	<CABdHhvFsgRMN0tFZTB6q1dbS7AHDbN_+BP_SU+QXL9ap94WFfQ@mail.gmail.com>
	<CAOQ5NyeF8fDYGwES0sy5eQfgFriK4Hos7vqX9R2YxkLgTPrhmg@mail.gmail.com>
Message-ID: <90626317-e7be-d3f3-5194-99fc714b5348@rstudio.com>

ML> For the uqs() thing, expanding calls like that is somewhat orthogonal
ML> to NSE. It would be nice in general to be able to write something like
ML> mean(x, extra_args...) without resorting to do.call(mean, c(list(x),
ML> extra_args)).

This is not completely true because splicing is necessarily linked to
the principle of unquoting (evaluating). You cannot splice something
that you don't know the value of, you have to evaluate the promise of
the splicing operand. In other words, you cannot splice at the parser
level, only at the interpreter level, and the splicing operation has
to be part of the call tree. This implies the important limitation
that you cannot splice a list in a call to a function taking named
arguments, you can only splice when capturing dots. On the plus side,
it seems more R-like to implement it as a regular function call since
all syntactic operations in R are function calls.

Since splicing is conceptually linked to unquoting, I think it would
make sense to have a derivative operator, e.g. @@. In that case it
would simply take its argument by expression and could thus be defined
as:

     `@@` <- `~`.

It'd be used like this:

     # Equivalent to as.list(mtcars)
     list(@@ mtcars)

     # Returns a list of symbols
     list(@@ lapply(letters, as.symbol))

To make it work we'd have two functions for capturing dots that would
understand arguments wrapped in an `@@` quosure. dotsValues(...)
would expand spliced arguments and then evaluate them, while
dotsExprs(...)  would expand and return a list of quosures. Dotted
primitive functions like list() or c() would also need to preprocess
the dots with a C function.

Another reason not to use `...` as syntax for splicing is that it may
be better to reserve it for forwarding operations. I think one other
syntax update that would be worthwile to consider is forwarding of
named arguments. This would allow labelling of arguments to work
transparently across wrappers:

     my_plot <- function(x) plot(1:10, ...(x))

     # The y axis is correctly labelled as 11:20 in the plot
     my_plot(11:20)

And this would also allow to forward named arguments to functions
taking their arguments by expression, just like we forward dots.

Lionel



[Rd] RFC: (in-principle) native unquoting for standard evaluation
Lionel Henry