Closed flying-sheep closed 4 years ago
This would be hard to achieve given the current implementation.
Reopening as I think we can fix this problem by abandoning support for a corner case (dots coming from multiple environments).
Actually we can't solve this without breaking support for NSE functions. I have added an explanation in the documentation:
#' `partial()` creates a function that takes `...` arguments. Unlike
#' [compose()] and other function operators like [negate()], it
#' doesn't reuse the function signature of `.f`. This is because
#' `partial()` explicitly supports NSE functions that use
#' `substitute()` on their arguments. The only way to support those is
#' to forward arguments through dots.
Actually I have some experience with this. It is possible to modify ...
without evaluating it. pryr::dots()
is just:
dots <- function(...) {
eval(substitute(alist(...)))
}
that way we can tinker with the unevaluated dots and then pass them on. Or am I missing something?
The problem is that partial(plot, 1:3)
with updated formals creates this function (simplified for the example):
function(y) plot(1:3, y)
Then when plot()
uses substitute()
on its argument, it correctly finds 1:3
, but incorrectly finds y
.
This is why partial()
uses dots, so that substitute()
(and tidyeval equivalents) work out of the box:
function(...) plot(1:3, ...)
To my knowledge there is no other way to fix this. You might try to create an NSE function that defuses and forwards arguments, but then you'll run into issues of incorrect evaluation environments, unless you use quosures. This will add overhead to the function created by partial()
, and we've just removed all the overhead.
It is possible to modify ... without evaluating it. pryr::dots() is
I recommend using quosures for capturing dots. Since dots may be forwarded across different levels of functions, the parent.frame()
is not the correct evaluation environment in the general case.
OK, I see. Thank you for the explanation!
Autocompletion for
partial(f, arg1 = 1)(<tab>
just results in... =
, instead of listing f’s signature.The
formals
of thepartialized
function should be updated.